# This file was auto-generated by Fern from our API Definition.

from ..core.client_wrapper import SyncClientWrapper
import typing
from ..generated_types.types.relationships import Relationships
from ..generated_types.types.country import Country
from ..generated_types.types.entities import Entities
from ..core.request_options import RequestOptions
from .types.traversal_response import TraversalResponse
from ..core.jsonable_encoder import jsonable_encoder
from ..core.pydantic_utilities import parse_obj_as
from ..shared_errors.errors.bad_request import BadRequest
from ..shared_errors.types.bad_request_response import BadRequestResponse
from ..shared_errors.errors.unauthorized import Unauthorized
from ..shared_errors.types.unauthorized_response import UnauthorizedResponse
from ..shared_errors.errors.not_found import NotFound
from ..shared_errors.types.not_found_response import NotFoundResponse
from ..shared_errors.errors.method_not_allowed import MethodNotAllowed
from ..shared_errors.types.method_not_allowed_response import MethodNotAllowedResponse
from ..shared_errors.errors.rate_limit_exceeded import RateLimitExceeded
from ..shared_errors.types.rate_limit_response import RateLimitResponse
from ..shared_errors.errors.internal_server_error import InternalServerError
from ..shared_errors.types.internal_server_error_response import InternalServerErrorResponse
from ..shared_errors.errors.bad_gateway import BadGateway
from ..shared_errors.types.bad_gateway_response import BadGatewayResponse
from ..shared_errors.errors.connection_error import ConnectionError
from ..shared_errors.types.connection_error_response import ConnectionErrorResponse
from json.decoder import JSONDecodeError
from ..core.api_error import ApiError
from .types.shortest_path_response import ShortestPathResponse
from ..core.client_wrapper import AsyncClientWrapper


class TraversalClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def traversal(
        self,
        id: str,
        *,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        min_depth: typing.Optional[int] = None,
        max_depth: typing.Optional[int] = None,
        relationships: typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]] = None,
        psa: typing.Optional[bool] = None,
        countries: typing.Optional[typing.Union[Country, typing.Sequence[Country]]] = None,
        types: typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]] = None,
        sanctioned: typing.Optional[bool] = None,
        pep: typing.Optional[bool] = None,
        min_shares: typing.Optional[int] = None,
        include_unknown_shares: typing.Optional[bool] = None,
        exclude_former_relationships: typing.Optional[bool] = None,
        exclude_closed_entities: typing.Optional[bool] = None,
        eu_high_risk_third: typing.Optional[bool] = None,
        reputational_risk_modern_slavery: typing.Optional[bool] = None,
        state_owned: typing.Optional[bool] = None,
        formerly_sanctioned: typing.Optional[bool] = None,
        reputational_risk_terrorism: typing.Optional[bool] = None,
        reputational_risk_organized_crime: typing.Optional[bool] = None,
        reputational_risk_financial_crime: typing.Optional[bool] = None,
        reputational_risk_bribery_and_corruption: typing.Optional[bool] = None,
        reputational_risk_other: typing.Optional[bool] = None,
        reputational_risk_cybercrime: typing.Optional[bool] = None,
        regulatory_action: typing.Optional[bool] = None,
        law_enforcement_action: typing.Optional[bool] = None,
        xinjiang_geospatial: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TraversalResponse:
        """
        The Traversal endpoint returns paths from a single target entity to up to 50 directly or indirectly-related entities. Each path includes information on the 0 to 10 intermediary entities, as well as their connecting relationships. The response's explored_count field indicates the size of the graph subset the application searched. Running a traversal on a highly connected entity with a restrictive set of argument filters and a high max depth will require the application to explore a higher number of traversal paths, which may affect performance. In cases where a traversal searches over a very large, highly-connected subgraph, a partial result set may be returned containing only the most relevant results. This will be indicated in the response by the partial_results field.

        Parameters
        ----------
        id : str
            Unique identifier of the entity

        limit : typing.Optional[int]
            Limit total values for traversal. Defaults to 10. Max of 50.

        offset : typing.Optional[int]
            Offset values for traversal. Defaults to 0. Max of 1000.

        min_depth : typing.Optional[int]
            Set minimum depth for traversal. Defaults to 1.

        max_depth : typing.Optional[int]
            Set maximum depth for traversal. Defaults to 4.

        relationships : typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]]
            Set relationship type(s) to follow when traversing related entities. Defaults to following all relationship types.

        psa : typing.Optional[bool]
            Also traverse relationships from entities that are possibly the same as any entity that appears in the path. Defaults to traversing possibly same as relationships.

        countries : typing.Optional[typing.Union[Country, typing.Sequence[Country]]]
            Filter paths to only those that end at an entity associated with the specified country(ies). Defaults to returning paths that end in any [country](/sayari-library/ontology/enumerated-types#country).

        types : typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]]
            Filter paths to only those that end at an entity of the specified type(s). Defaults to returning paths that end at any type.

        sanctioned : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a watchlist. Defaults to not filtering paths by sanctioned status.

        pep : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a pep list. Defaults to not filtering paths by pep status.

        min_shares : typing.Optional[int]
            Set minimum percentage of share ownership for traversal. Defaults to 0.

        include_unknown_shares : typing.Optional[bool]
            Also traverse relationships when share percentages are unknown. Only useful when min_shares is set greater than 0. Defaults to true.

        exclude_former_relationships : typing.Optional[bool]
            Include relationships that were valid in the past but not at the present time. Defaults to true.

        exclude_closed_entities : typing.Optional[bool]
            Include entities that existed in the past but not at the present time. Defaults to false.

        eu_high_risk_third : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_modern_slavery : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        state_owned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        formerly_sanctioned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_terrorism : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_organized_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_financial_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_bribery_and_corruption : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_other : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_cybercrime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        regulatory_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        law_enforcement_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        xinjiang_geospatial : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TraversalResponse

        Examples
        --------
        from sayari import Sayari

        client = Sayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.traversal.traversal(
            id="mGq1lpuqKssNWTjIokuPeA",
            limit=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/traversal/{jsonable_encoder(id)}",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "min_depth": min_depth,
                "max_depth": max_depth,
                "relationships": relationships,
                "psa": psa,
                "countries": countries,
                "types": types,
                "sanctioned": sanctioned,
                "pep": pep,
                "min_shares": min_shares,
                "include_unknown_shares": include_unknown_shares,
                "exclude_former_relationships": exclude_former_relationships,
                "exclude_closed_entities": exclude_closed_entities,
                "eu_high_risk_third": eu_high_risk_third,
                "reputational_risk_modern_slavery": reputational_risk_modern_slavery,
                "state_owned": state_owned,
                "formerly_sanctioned": formerly_sanctioned,
                "reputational_risk_terrorism": reputational_risk_terrorism,
                "reputational_risk_organized_crime": reputational_risk_organized_crime,
                "reputational_risk_financial_crime": reputational_risk_financial_crime,
                "reputational_risk_bribery_and_corruption": reputational_risk_bribery_and_corruption,
                "reputational_risk_other": reputational_risk_other,
                "reputational_risk_cybercrime": reputational_risk_cybercrime,
                "regulatory_action": regulatory_action,
                "law_enforcement_action": law_enforcement_action,
                "xinjiang_geospatial": xinjiang_geospatial,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TraversalResponse,
                    parse_obj_as(
                        type_=TraversalResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def ubo(
        self,
        id: str,
        *,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        min_depth: typing.Optional[int] = None,
        max_depth: typing.Optional[int] = None,
        relationships: typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]] = None,
        psa: typing.Optional[bool] = None,
        countries: typing.Optional[typing.Union[Country, typing.Sequence[Country]]] = None,
        types: typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]] = None,
        sanctioned: typing.Optional[bool] = None,
        pep: typing.Optional[bool] = None,
        min_shares: typing.Optional[int] = None,
        include_unknown_shares: typing.Optional[bool] = None,
        exclude_former_relationships: typing.Optional[bool] = None,
        exclude_closed_entities: typing.Optional[bool] = None,
        eu_high_risk_third: typing.Optional[bool] = None,
        reputational_risk_modern_slavery: typing.Optional[bool] = None,
        state_owned: typing.Optional[bool] = None,
        formerly_sanctioned: typing.Optional[bool] = None,
        reputational_risk_terrorism: typing.Optional[bool] = None,
        reputational_risk_organized_crime: typing.Optional[bool] = None,
        reputational_risk_financial_crime: typing.Optional[bool] = None,
        reputational_risk_bribery_and_corruption: typing.Optional[bool] = None,
        reputational_risk_other: typing.Optional[bool] = None,
        reputational_risk_cybercrime: typing.Optional[bool] = None,
        regulatory_action: typing.Optional[bool] = None,
        law_enforcement_action: typing.Optional[bool] = None,
        xinjiang_geospatial: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TraversalResponse:
        """
        The UBO endpoint returns paths from a single target entity to up to 50 beneficial owners. The endpoint is a shorthand for the equivalent traversal query.

        Parameters
        ----------
        id : str
            Unique identifier of the entity

        limit : typing.Optional[int]
            Limit total values for traversal. Defaults to 10. Max of 50.

        offset : typing.Optional[int]
            Offset values for traversal. Defaults to 0. Max of 1000.

        min_depth : typing.Optional[int]
            Set minimum depth for traversal. Defaults to 1.

        max_depth : typing.Optional[int]
            Set maximum depth for traversal. Defaults to 4.

        relationships : typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]]
            Set relationship type(s) to follow when traversing related entities. Defaults to has_shareholder, has_beneficial_owner, has_partner, subsidiary_of, and branch_of.

        psa : typing.Optional[bool]
            Also traverse relationships from entities that are possibly the same as any entity that appears in the path. Defaults to traversing possibly same as relationships.

        countries : typing.Optional[typing.Union[Country, typing.Sequence[Country]]]
            Filter paths to only those that end at an entity associated with the specified country(ies). Defaults to returning paths that end in any [country](/sayari-library/ontology/enumerated-types#country).

        types : typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]]
            Filter paths to only those that end at an entity of the specified type(s). Defaults to returning paths that end at any type.

        sanctioned : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a watchlist. Defaults to not filtering paths by sanctioned status.

        pep : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a pep list. Defaults to not filtering paths by pep status.

        min_shares : typing.Optional[int]
            Set minimum percentage of share ownership for traversal. Defaults to 0.

        include_unknown_shares : typing.Optional[bool]
            Also traverse relationships when share percentages are unknown. Only useful when min_shares is set greater than 0. Defaults to true.

        exclude_former_relationships : typing.Optional[bool]
            Include relationships that were valid in the past but not at the present time. Defaults to true.

        exclude_closed_entities : typing.Optional[bool]
            Include entities that existed in the past but not at the present time. Defaults to false.

        eu_high_risk_third : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_modern_slavery : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        state_owned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        formerly_sanctioned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_terrorism : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_organized_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_financial_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_bribery_and_corruption : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_other : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_cybercrime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        regulatory_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        law_enforcement_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        xinjiang_geospatial : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TraversalResponse

        Examples
        --------
        from sayari import Sayari

        client = Sayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.traversal.ubo(
            id="mGq1lpuqKssNWTjIokuPeA",
            limit=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/ubo/{jsonable_encoder(id)}",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "min_depth": min_depth,
                "max_depth": max_depth,
                "relationships": relationships,
                "psa": psa,
                "countries": countries,
                "types": types,
                "sanctioned": sanctioned,
                "pep": pep,
                "min_shares": min_shares,
                "include_unknown_shares": include_unknown_shares,
                "exclude_former_relationships": exclude_former_relationships,
                "exclude_closed_entities": exclude_closed_entities,
                "eu_high_risk_third": eu_high_risk_third,
                "reputational_risk_modern_slavery": reputational_risk_modern_slavery,
                "state_owned": state_owned,
                "formerly_sanctioned": formerly_sanctioned,
                "reputational_risk_terrorism": reputational_risk_terrorism,
                "reputational_risk_organized_crime": reputational_risk_organized_crime,
                "reputational_risk_financial_crime": reputational_risk_financial_crime,
                "reputational_risk_bribery_and_corruption": reputational_risk_bribery_and_corruption,
                "reputational_risk_other": reputational_risk_other,
                "reputational_risk_cybercrime": reputational_risk_cybercrime,
                "regulatory_action": regulatory_action,
                "law_enforcement_action": law_enforcement_action,
                "xinjiang_geospatial": xinjiang_geospatial,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TraversalResponse,
                    parse_obj_as(
                        type_=TraversalResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def ownership(
        self,
        id: str,
        *,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        min_depth: typing.Optional[int] = None,
        max_depth: typing.Optional[int] = None,
        relationships: typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]] = None,
        psa: typing.Optional[bool] = None,
        countries: typing.Optional[typing.Union[Country, typing.Sequence[Country]]] = None,
        types: typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]] = None,
        sanctioned: typing.Optional[bool] = None,
        pep: typing.Optional[bool] = None,
        min_shares: typing.Optional[int] = None,
        include_unknown_shares: typing.Optional[bool] = None,
        exclude_former_relationships: typing.Optional[bool] = None,
        exclude_closed_entities: typing.Optional[bool] = None,
        eu_high_risk_third: typing.Optional[bool] = None,
        reputational_risk_modern_slavery: typing.Optional[bool] = None,
        state_owned: typing.Optional[bool] = None,
        formerly_sanctioned: typing.Optional[bool] = None,
        reputational_risk_terrorism: typing.Optional[bool] = None,
        reputational_risk_organized_crime: typing.Optional[bool] = None,
        reputational_risk_financial_crime: typing.Optional[bool] = None,
        reputational_risk_bribery_and_corruption: typing.Optional[bool] = None,
        reputational_risk_other: typing.Optional[bool] = None,
        reputational_risk_cybercrime: typing.Optional[bool] = None,
        regulatory_action: typing.Optional[bool] = None,
        law_enforcement_action: typing.Optional[bool] = None,
        xinjiang_geospatial: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TraversalResponse:
        """
        The Ownership endpoint returns paths from a single target entity to up to 50 entities directly or indirectly owned by that entity. The endpoint is a shorthand for the equivalent traversal query.

        Parameters
        ----------
        id : str
            Unique identifier of the entity

        limit : typing.Optional[int]
            Limit total values for traversal. Defaults to 10. Max of 50.

        offset : typing.Optional[int]
            Offset values for traversal. Defaults to 0. Max of 1000.

        min_depth : typing.Optional[int]
            Set minimum depth for traversal. Defaults to 1.

        max_depth : typing.Optional[int]
            Set maximum depth for traversal. Defaults to 4.

        relationships : typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]]
            Set relationship type(s) to follow when traversing related entities. Defaults to shareholder_of, beneficial_owner_of, partner_of, has_subsidiary, and has_branch.

        psa : typing.Optional[bool]
            Also traverse relationships from entities that are possibly the same as any entity that appears in the path. Defaults to traversing possibly same as relationships.

        countries : typing.Optional[typing.Union[Country, typing.Sequence[Country]]]
            Filter paths to only those that end at an entity associated with the specified country(ies). Defaults to returning paths that end in any country.

        types : typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]]
            Filter paths to only those that end at an entity of the specified type(s). Defaults to returning paths that end at any type.

        sanctioned : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a watchlist. Defaults to not filtering paths by sanctioned status.

        pep : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a pep list. Defaults to not filtering paths by pep status.

        min_shares : typing.Optional[int]
            Set minimum percentage of share ownership for traversal. Defaults to 0.

        include_unknown_shares : typing.Optional[bool]
            Also traverse relationships when share percentages are unknown. Only useful when min_shares is set greater than 0. Defaults to true.

        exclude_former_relationships : typing.Optional[bool]
            Include relationships that were valid in the past but not at the present time. Defaults to true.

        exclude_closed_entities : typing.Optional[bool]
            Include entities that existed in the past but not at the present time. Defaults to false.

        eu_high_risk_third : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_modern_slavery : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        state_owned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        formerly_sanctioned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_terrorism : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_organized_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_financial_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_bribery_and_corruption : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_other : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_cybercrime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        regulatory_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        law_enforcement_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        xinjiang_geospatial : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TraversalResponse

        Examples
        --------
        from sayari import Sayari

        client = Sayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.traversal.ownership(
            id="mGq1lpuqKssNWTjIokuPeA",
            limit=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/downstream/{jsonable_encoder(id)}",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "min_depth": min_depth,
                "max_depth": max_depth,
                "relationships": relationships,
                "psa": psa,
                "countries": countries,
                "types": types,
                "sanctioned": sanctioned,
                "pep": pep,
                "min_shares": min_shares,
                "include_unknown_shares": include_unknown_shares,
                "exclude_former_relationships": exclude_former_relationships,
                "exclude_closed_entities": exclude_closed_entities,
                "eu_high_risk_third": eu_high_risk_third,
                "reputational_risk_modern_slavery": reputational_risk_modern_slavery,
                "state_owned": state_owned,
                "formerly_sanctioned": formerly_sanctioned,
                "reputational_risk_terrorism": reputational_risk_terrorism,
                "reputational_risk_organized_crime": reputational_risk_organized_crime,
                "reputational_risk_financial_crime": reputational_risk_financial_crime,
                "reputational_risk_bribery_and_corruption": reputational_risk_bribery_and_corruption,
                "reputational_risk_other": reputational_risk_other,
                "reputational_risk_cybercrime": reputational_risk_cybercrime,
                "regulatory_action": regulatory_action,
                "law_enforcement_action": law_enforcement_action,
                "xinjiang_geospatial": xinjiang_geospatial,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TraversalResponse,
                    parse_obj_as(
                        type_=TraversalResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def watchlist(
        self,
        id: str,
        *,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        min_depth: typing.Optional[int] = None,
        max_depth: typing.Optional[int] = None,
        relationships: typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]] = None,
        psa: typing.Optional[bool] = None,
        countries: typing.Optional[typing.Union[Country, typing.Sequence[Country]]] = None,
        types: typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]] = None,
        sanctioned: typing.Optional[bool] = None,
        pep: typing.Optional[bool] = None,
        min_shares: typing.Optional[int] = None,
        include_unknown_shares: typing.Optional[bool] = None,
        exclude_former_relationships: typing.Optional[bool] = None,
        exclude_closed_entities: typing.Optional[bool] = None,
        eu_high_risk_third: typing.Optional[bool] = None,
        reputational_risk_modern_slavery: typing.Optional[bool] = None,
        state_owned: typing.Optional[bool] = None,
        formerly_sanctioned: typing.Optional[bool] = None,
        reputational_risk_terrorism: typing.Optional[bool] = None,
        reputational_risk_organized_crime: typing.Optional[bool] = None,
        reputational_risk_financial_crime: typing.Optional[bool] = None,
        reputational_risk_bribery_and_corruption: typing.Optional[bool] = None,
        reputational_risk_other: typing.Optional[bool] = None,
        reputational_risk_cybercrime: typing.Optional[bool] = None,
        regulatory_action: typing.Optional[bool] = None,
        law_enforcement_action: typing.Optional[bool] = None,
        xinjiang_geospatial: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TraversalResponse:
        """
        The Watchlist endpoint returns paths from a single target entity to up to 50 other entities that appear on a watchlist. The endpoint is a shorthand for the equivalent traversal query.

        Parameters
        ----------
        id : str
            Unique identifier of the entity

        limit : typing.Optional[int]
            Limit total values for traversal. Defaults to 10. Max of 50.

        offset : typing.Optional[int]
            Offset values for traversal. Defaults to 0. Max of 1000.

        min_depth : typing.Optional[int]
            Set minimum depth for traversal. Defaults to 1.

        max_depth : typing.Optional[int]
            Set maximum depth for traversal. Defaults to 4.

        relationships : typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]]
            Set relationship type(s) to follow when traversing related entities. Defaults to following 31 relevant relationship types covering ownership, control, and trade.

        psa : typing.Optional[bool]
            Also traverse relationships from entities that are possibly the same as any entity that appears in the path. Defaults to traversing possibly same as relationships.

        countries : typing.Optional[typing.Union[Country, typing.Sequence[Country]]]
            Filter paths to only those that end at an entity associated with the specified country(ies). Defaults to returning paths that end in any country.

        types : typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]]
            Filter paths to only those that end at an entity of the specified type(s). Defaults to returning paths that end at any type.

        sanctioned : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a watchlist. Defaults to not filtering paths by sanctioned status.

        pep : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a pep list. Defaults to not filtering paths by pep status.

        min_shares : typing.Optional[int]
            Set minimum percentage of share ownership for traversal. Defaults to 0.

        include_unknown_shares : typing.Optional[bool]
            Also traverse relationships when share percentages are unknown. Only useful when min_shares is set greater than 0. Defaults to true.

        exclude_former_relationships : typing.Optional[bool]
            Include relationships that were valid in the past but not at the present time. Defaults to false.

        exclude_closed_entities : typing.Optional[bool]
            Include entities that existed in the past but not at the present time. Defaults to false.

        eu_high_risk_third : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_modern_slavery : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        state_owned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        formerly_sanctioned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_terrorism : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_organized_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_financial_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_bribery_and_corruption : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_other : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_cybercrime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        regulatory_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        law_enforcement_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        xinjiang_geospatial : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TraversalResponse

        Examples
        --------
        from sayari import Sayari

        client = Sayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.traversal.watchlist(
            id="mGq1lpuqKssNWTjIokuPeA",
            limit=1,
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            f"v1/watchlist/{jsonable_encoder(id)}",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "min_depth": min_depth,
                "max_depth": max_depth,
                "relationships": relationships,
                "psa": psa,
                "countries": countries,
                "types": types,
                "sanctioned": sanctioned,
                "pep": pep,
                "min_shares": min_shares,
                "include_unknown_shares": include_unknown_shares,
                "exclude_former_relationships": exclude_former_relationships,
                "exclude_closed_entities": exclude_closed_entities,
                "eu_high_risk_third": eu_high_risk_third,
                "reputational_risk_modern_slavery": reputational_risk_modern_slavery,
                "state_owned": state_owned,
                "formerly_sanctioned": formerly_sanctioned,
                "reputational_risk_terrorism": reputational_risk_terrorism,
                "reputational_risk_organized_crime": reputational_risk_organized_crime,
                "reputational_risk_financial_crime": reputational_risk_financial_crime,
                "reputational_risk_bribery_and_corruption": reputational_risk_bribery_and_corruption,
                "reputational_risk_other": reputational_risk_other,
                "reputational_risk_cybercrime": reputational_risk_cybercrime,
                "regulatory_action": regulatory_action,
                "law_enforcement_action": law_enforcement_action,
                "xinjiang_geospatial": xinjiang_geospatial,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TraversalResponse,
                    parse_obj_as(
                        type_=TraversalResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    def shortest_path(
        self,
        *,
        entities: typing.Union[str, typing.Sequence[str]],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ShortestPathResponse:
        """
        The Shortest Path endpoint returns a response identifying the shortest traversal path connecting each pair of entities.

        Parameters
        ----------
        entities : typing.Union[str, typing.Sequence[str]]
            A list of Sayari entity IDs specifying the source and target entities for the shortest path calculation. The list must contain exactly two entity IDs The first entity ID represents the source.The second entity ID represents the target.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        ShortestPathResponse

        Examples
        --------
        from sayari import Sayari

        client = Sayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.traversal.shortest_path(
            entities="H1y25N5ymnFyZ-q9Lpwm_g&entities=xthsA_jQuKn3GW8-9ILQqg",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/shortest_path",
            method="GET",
            params={
                "entities": entities,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ShortestPathResponse,
                    parse_obj_as(
                        type_=ShortestPathResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)


class AsyncTraversalClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def traversal(
        self,
        id: str,
        *,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        min_depth: typing.Optional[int] = None,
        max_depth: typing.Optional[int] = None,
        relationships: typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]] = None,
        psa: typing.Optional[bool] = None,
        countries: typing.Optional[typing.Union[Country, typing.Sequence[Country]]] = None,
        types: typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]] = None,
        sanctioned: typing.Optional[bool] = None,
        pep: typing.Optional[bool] = None,
        min_shares: typing.Optional[int] = None,
        include_unknown_shares: typing.Optional[bool] = None,
        exclude_former_relationships: typing.Optional[bool] = None,
        exclude_closed_entities: typing.Optional[bool] = None,
        eu_high_risk_third: typing.Optional[bool] = None,
        reputational_risk_modern_slavery: typing.Optional[bool] = None,
        state_owned: typing.Optional[bool] = None,
        formerly_sanctioned: typing.Optional[bool] = None,
        reputational_risk_terrorism: typing.Optional[bool] = None,
        reputational_risk_organized_crime: typing.Optional[bool] = None,
        reputational_risk_financial_crime: typing.Optional[bool] = None,
        reputational_risk_bribery_and_corruption: typing.Optional[bool] = None,
        reputational_risk_other: typing.Optional[bool] = None,
        reputational_risk_cybercrime: typing.Optional[bool] = None,
        regulatory_action: typing.Optional[bool] = None,
        law_enforcement_action: typing.Optional[bool] = None,
        xinjiang_geospatial: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TraversalResponse:
        """
        The Traversal endpoint returns paths from a single target entity to up to 50 directly or indirectly-related entities. Each path includes information on the 0 to 10 intermediary entities, as well as their connecting relationships. The response's explored_count field indicates the size of the graph subset the application searched. Running a traversal on a highly connected entity with a restrictive set of argument filters and a high max depth will require the application to explore a higher number of traversal paths, which may affect performance. In cases where a traversal searches over a very large, highly-connected subgraph, a partial result set may be returned containing only the most relevant results. This will be indicated in the response by the partial_results field.

        Parameters
        ----------
        id : str
            Unique identifier of the entity

        limit : typing.Optional[int]
            Limit total values for traversal. Defaults to 10. Max of 50.

        offset : typing.Optional[int]
            Offset values for traversal. Defaults to 0. Max of 1000.

        min_depth : typing.Optional[int]
            Set minimum depth for traversal. Defaults to 1.

        max_depth : typing.Optional[int]
            Set maximum depth for traversal. Defaults to 4.

        relationships : typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]]
            Set relationship type(s) to follow when traversing related entities. Defaults to following all relationship types.

        psa : typing.Optional[bool]
            Also traverse relationships from entities that are possibly the same as any entity that appears in the path. Defaults to traversing possibly same as relationships.

        countries : typing.Optional[typing.Union[Country, typing.Sequence[Country]]]
            Filter paths to only those that end at an entity associated with the specified country(ies). Defaults to returning paths that end in any [country](/sayari-library/ontology/enumerated-types#country).

        types : typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]]
            Filter paths to only those that end at an entity of the specified type(s). Defaults to returning paths that end at any type.

        sanctioned : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a watchlist. Defaults to not filtering paths by sanctioned status.

        pep : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a pep list. Defaults to not filtering paths by pep status.

        min_shares : typing.Optional[int]
            Set minimum percentage of share ownership for traversal. Defaults to 0.

        include_unknown_shares : typing.Optional[bool]
            Also traverse relationships when share percentages are unknown. Only useful when min_shares is set greater than 0. Defaults to true.

        exclude_former_relationships : typing.Optional[bool]
            Include relationships that were valid in the past but not at the present time. Defaults to true.

        exclude_closed_entities : typing.Optional[bool]
            Include entities that existed in the past but not at the present time. Defaults to false.

        eu_high_risk_third : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_modern_slavery : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        state_owned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        formerly_sanctioned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_terrorism : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_organized_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_financial_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_bribery_and_corruption : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_other : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_cybercrime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        regulatory_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        law_enforcement_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        xinjiang_geospatial : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TraversalResponse

        Examples
        --------
        import asyncio

        from sayari import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.traversal.traversal(
                id="mGq1lpuqKssNWTjIokuPeA",
                limit=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/traversal/{jsonable_encoder(id)}",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "min_depth": min_depth,
                "max_depth": max_depth,
                "relationships": relationships,
                "psa": psa,
                "countries": countries,
                "types": types,
                "sanctioned": sanctioned,
                "pep": pep,
                "min_shares": min_shares,
                "include_unknown_shares": include_unknown_shares,
                "exclude_former_relationships": exclude_former_relationships,
                "exclude_closed_entities": exclude_closed_entities,
                "eu_high_risk_third": eu_high_risk_third,
                "reputational_risk_modern_slavery": reputational_risk_modern_slavery,
                "state_owned": state_owned,
                "formerly_sanctioned": formerly_sanctioned,
                "reputational_risk_terrorism": reputational_risk_terrorism,
                "reputational_risk_organized_crime": reputational_risk_organized_crime,
                "reputational_risk_financial_crime": reputational_risk_financial_crime,
                "reputational_risk_bribery_and_corruption": reputational_risk_bribery_and_corruption,
                "reputational_risk_other": reputational_risk_other,
                "reputational_risk_cybercrime": reputational_risk_cybercrime,
                "regulatory_action": regulatory_action,
                "law_enforcement_action": law_enforcement_action,
                "xinjiang_geospatial": xinjiang_geospatial,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TraversalResponse,
                    parse_obj_as(
                        type_=TraversalResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def ubo(
        self,
        id: str,
        *,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        min_depth: typing.Optional[int] = None,
        max_depth: typing.Optional[int] = None,
        relationships: typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]] = None,
        psa: typing.Optional[bool] = None,
        countries: typing.Optional[typing.Union[Country, typing.Sequence[Country]]] = None,
        types: typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]] = None,
        sanctioned: typing.Optional[bool] = None,
        pep: typing.Optional[bool] = None,
        min_shares: typing.Optional[int] = None,
        include_unknown_shares: typing.Optional[bool] = None,
        exclude_former_relationships: typing.Optional[bool] = None,
        exclude_closed_entities: typing.Optional[bool] = None,
        eu_high_risk_third: typing.Optional[bool] = None,
        reputational_risk_modern_slavery: typing.Optional[bool] = None,
        state_owned: typing.Optional[bool] = None,
        formerly_sanctioned: typing.Optional[bool] = None,
        reputational_risk_terrorism: typing.Optional[bool] = None,
        reputational_risk_organized_crime: typing.Optional[bool] = None,
        reputational_risk_financial_crime: typing.Optional[bool] = None,
        reputational_risk_bribery_and_corruption: typing.Optional[bool] = None,
        reputational_risk_other: typing.Optional[bool] = None,
        reputational_risk_cybercrime: typing.Optional[bool] = None,
        regulatory_action: typing.Optional[bool] = None,
        law_enforcement_action: typing.Optional[bool] = None,
        xinjiang_geospatial: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TraversalResponse:
        """
        The UBO endpoint returns paths from a single target entity to up to 50 beneficial owners. The endpoint is a shorthand for the equivalent traversal query.

        Parameters
        ----------
        id : str
            Unique identifier of the entity

        limit : typing.Optional[int]
            Limit total values for traversal. Defaults to 10. Max of 50.

        offset : typing.Optional[int]
            Offset values for traversal. Defaults to 0. Max of 1000.

        min_depth : typing.Optional[int]
            Set minimum depth for traversal. Defaults to 1.

        max_depth : typing.Optional[int]
            Set maximum depth for traversal. Defaults to 4.

        relationships : typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]]
            Set relationship type(s) to follow when traversing related entities. Defaults to has_shareholder, has_beneficial_owner, has_partner, subsidiary_of, and branch_of.

        psa : typing.Optional[bool]
            Also traverse relationships from entities that are possibly the same as any entity that appears in the path. Defaults to traversing possibly same as relationships.

        countries : typing.Optional[typing.Union[Country, typing.Sequence[Country]]]
            Filter paths to only those that end at an entity associated with the specified country(ies). Defaults to returning paths that end in any [country](/sayari-library/ontology/enumerated-types#country).

        types : typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]]
            Filter paths to only those that end at an entity of the specified type(s). Defaults to returning paths that end at any type.

        sanctioned : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a watchlist. Defaults to not filtering paths by sanctioned status.

        pep : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a pep list. Defaults to not filtering paths by pep status.

        min_shares : typing.Optional[int]
            Set minimum percentage of share ownership for traversal. Defaults to 0.

        include_unknown_shares : typing.Optional[bool]
            Also traverse relationships when share percentages are unknown. Only useful when min_shares is set greater than 0. Defaults to true.

        exclude_former_relationships : typing.Optional[bool]
            Include relationships that were valid in the past but not at the present time. Defaults to true.

        exclude_closed_entities : typing.Optional[bool]
            Include entities that existed in the past but not at the present time. Defaults to false.

        eu_high_risk_third : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_modern_slavery : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        state_owned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        formerly_sanctioned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_terrorism : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_organized_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_financial_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_bribery_and_corruption : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_other : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_cybercrime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        regulatory_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        law_enforcement_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        xinjiang_geospatial : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TraversalResponse

        Examples
        --------
        import asyncio

        from sayari import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.traversal.ubo(
                id="mGq1lpuqKssNWTjIokuPeA",
                limit=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/ubo/{jsonable_encoder(id)}",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "min_depth": min_depth,
                "max_depth": max_depth,
                "relationships": relationships,
                "psa": psa,
                "countries": countries,
                "types": types,
                "sanctioned": sanctioned,
                "pep": pep,
                "min_shares": min_shares,
                "include_unknown_shares": include_unknown_shares,
                "exclude_former_relationships": exclude_former_relationships,
                "exclude_closed_entities": exclude_closed_entities,
                "eu_high_risk_third": eu_high_risk_third,
                "reputational_risk_modern_slavery": reputational_risk_modern_slavery,
                "state_owned": state_owned,
                "formerly_sanctioned": formerly_sanctioned,
                "reputational_risk_terrorism": reputational_risk_terrorism,
                "reputational_risk_organized_crime": reputational_risk_organized_crime,
                "reputational_risk_financial_crime": reputational_risk_financial_crime,
                "reputational_risk_bribery_and_corruption": reputational_risk_bribery_and_corruption,
                "reputational_risk_other": reputational_risk_other,
                "reputational_risk_cybercrime": reputational_risk_cybercrime,
                "regulatory_action": regulatory_action,
                "law_enforcement_action": law_enforcement_action,
                "xinjiang_geospatial": xinjiang_geospatial,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TraversalResponse,
                    parse_obj_as(
                        type_=TraversalResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def ownership(
        self,
        id: str,
        *,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        min_depth: typing.Optional[int] = None,
        max_depth: typing.Optional[int] = None,
        relationships: typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]] = None,
        psa: typing.Optional[bool] = None,
        countries: typing.Optional[typing.Union[Country, typing.Sequence[Country]]] = None,
        types: typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]] = None,
        sanctioned: typing.Optional[bool] = None,
        pep: typing.Optional[bool] = None,
        min_shares: typing.Optional[int] = None,
        include_unknown_shares: typing.Optional[bool] = None,
        exclude_former_relationships: typing.Optional[bool] = None,
        exclude_closed_entities: typing.Optional[bool] = None,
        eu_high_risk_third: typing.Optional[bool] = None,
        reputational_risk_modern_slavery: typing.Optional[bool] = None,
        state_owned: typing.Optional[bool] = None,
        formerly_sanctioned: typing.Optional[bool] = None,
        reputational_risk_terrorism: typing.Optional[bool] = None,
        reputational_risk_organized_crime: typing.Optional[bool] = None,
        reputational_risk_financial_crime: typing.Optional[bool] = None,
        reputational_risk_bribery_and_corruption: typing.Optional[bool] = None,
        reputational_risk_other: typing.Optional[bool] = None,
        reputational_risk_cybercrime: typing.Optional[bool] = None,
        regulatory_action: typing.Optional[bool] = None,
        law_enforcement_action: typing.Optional[bool] = None,
        xinjiang_geospatial: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TraversalResponse:
        """
        The Ownership endpoint returns paths from a single target entity to up to 50 entities directly or indirectly owned by that entity. The endpoint is a shorthand for the equivalent traversal query.

        Parameters
        ----------
        id : str
            Unique identifier of the entity

        limit : typing.Optional[int]
            Limit total values for traversal. Defaults to 10. Max of 50.

        offset : typing.Optional[int]
            Offset values for traversal. Defaults to 0. Max of 1000.

        min_depth : typing.Optional[int]
            Set minimum depth for traversal. Defaults to 1.

        max_depth : typing.Optional[int]
            Set maximum depth for traversal. Defaults to 4.

        relationships : typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]]
            Set relationship type(s) to follow when traversing related entities. Defaults to shareholder_of, beneficial_owner_of, partner_of, has_subsidiary, and has_branch.

        psa : typing.Optional[bool]
            Also traverse relationships from entities that are possibly the same as any entity that appears in the path. Defaults to traversing possibly same as relationships.

        countries : typing.Optional[typing.Union[Country, typing.Sequence[Country]]]
            Filter paths to only those that end at an entity associated with the specified country(ies). Defaults to returning paths that end in any country.

        types : typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]]
            Filter paths to only those that end at an entity of the specified type(s). Defaults to returning paths that end at any type.

        sanctioned : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a watchlist. Defaults to not filtering paths by sanctioned status.

        pep : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a pep list. Defaults to not filtering paths by pep status.

        min_shares : typing.Optional[int]
            Set minimum percentage of share ownership for traversal. Defaults to 0.

        include_unknown_shares : typing.Optional[bool]
            Also traverse relationships when share percentages are unknown. Only useful when min_shares is set greater than 0. Defaults to true.

        exclude_former_relationships : typing.Optional[bool]
            Include relationships that were valid in the past but not at the present time. Defaults to true.

        exclude_closed_entities : typing.Optional[bool]
            Include entities that existed in the past but not at the present time. Defaults to false.

        eu_high_risk_third : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_modern_slavery : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        state_owned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        formerly_sanctioned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_terrorism : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_organized_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_financial_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_bribery_and_corruption : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_other : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_cybercrime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        regulatory_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        law_enforcement_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        xinjiang_geospatial : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TraversalResponse

        Examples
        --------
        import asyncio

        from sayari import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.traversal.ownership(
                id="mGq1lpuqKssNWTjIokuPeA",
                limit=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/downstream/{jsonable_encoder(id)}",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "min_depth": min_depth,
                "max_depth": max_depth,
                "relationships": relationships,
                "psa": psa,
                "countries": countries,
                "types": types,
                "sanctioned": sanctioned,
                "pep": pep,
                "min_shares": min_shares,
                "include_unknown_shares": include_unknown_shares,
                "exclude_former_relationships": exclude_former_relationships,
                "exclude_closed_entities": exclude_closed_entities,
                "eu_high_risk_third": eu_high_risk_third,
                "reputational_risk_modern_slavery": reputational_risk_modern_slavery,
                "state_owned": state_owned,
                "formerly_sanctioned": formerly_sanctioned,
                "reputational_risk_terrorism": reputational_risk_terrorism,
                "reputational_risk_organized_crime": reputational_risk_organized_crime,
                "reputational_risk_financial_crime": reputational_risk_financial_crime,
                "reputational_risk_bribery_and_corruption": reputational_risk_bribery_and_corruption,
                "reputational_risk_other": reputational_risk_other,
                "reputational_risk_cybercrime": reputational_risk_cybercrime,
                "regulatory_action": regulatory_action,
                "law_enforcement_action": law_enforcement_action,
                "xinjiang_geospatial": xinjiang_geospatial,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TraversalResponse,
                    parse_obj_as(
                        type_=TraversalResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def watchlist(
        self,
        id: str,
        *,
        limit: typing.Optional[int] = None,
        offset: typing.Optional[int] = None,
        min_depth: typing.Optional[int] = None,
        max_depth: typing.Optional[int] = None,
        relationships: typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]] = None,
        psa: typing.Optional[bool] = None,
        countries: typing.Optional[typing.Union[Country, typing.Sequence[Country]]] = None,
        types: typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]] = None,
        sanctioned: typing.Optional[bool] = None,
        pep: typing.Optional[bool] = None,
        min_shares: typing.Optional[int] = None,
        include_unknown_shares: typing.Optional[bool] = None,
        exclude_former_relationships: typing.Optional[bool] = None,
        exclude_closed_entities: typing.Optional[bool] = None,
        eu_high_risk_third: typing.Optional[bool] = None,
        reputational_risk_modern_slavery: typing.Optional[bool] = None,
        state_owned: typing.Optional[bool] = None,
        formerly_sanctioned: typing.Optional[bool] = None,
        reputational_risk_terrorism: typing.Optional[bool] = None,
        reputational_risk_organized_crime: typing.Optional[bool] = None,
        reputational_risk_financial_crime: typing.Optional[bool] = None,
        reputational_risk_bribery_and_corruption: typing.Optional[bool] = None,
        reputational_risk_other: typing.Optional[bool] = None,
        reputational_risk_cybercrime: typing.Optional[bool] = None,
        regulatory_action: typing.Optional[bool] = None,
        law_enforcement_action: typing.Optional[bool] = None,
        xinjiang_geospatial: typing.Optional[bool] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> TraversalResponse:
        """
        The Watchlist endpoint returns paths from a single target entity to up to 50 other entities that appear on a watchlist. The endpoint is a shorthand for the equivalent traversal query.

        Parameters
        ----------
        id : str
            Unique identifier of the entity

        limit : typing.Optional[int]
            Limit total values for traversal. Defaults to 10. Max of 50.

        offset : typing.Optional[int]
            Offset values for traversal. Defaults to 0. Max of 1000.

        min_depth : typing.Optional[int]
            Set minimum depth for traversal. Defaults to 1.

        max_depth : typing.Optional[int]
            Set maximum depth for traversal. Defaults to 4.

        relationships : typing.Optional[typing.Union[Relationships, typing.Sequence[Relationships]]]
            Set relationship type(s) to follow when traversing related entities. Defaults to following 31 relevant relationship types covering ownership, control, and trade.

        psa : typing.Optional[bool]
            Also traverse relationships from entities that are possibly the same as any entity that appears in the path. Defaults to traversing possibly same as relationships.

        countries : typing.Optional[typing.Union[Country, typing.Sequence[Country]]]
            Filter paths to only those that end at an entity associated with the specified country(ies). Defaults to returning paths that end in any country.

        types : typing.Optional[typing.Union[Entities, typing.Sequence[Entities]]]
            Filter paths to only those that end at an entity of the specified type(s). Defaults to returning paths that end at any type.

        sanctioned : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a watchlist. Defaults to not filtering paths by sanctioned status.

        pep : typing.Optional[bool]
            Filter paths to only those that end at an entity appearing on a pep list. Defaults to not filtering paths by pep status.

        min_shares : typing.Optional[int]
            Set minimum percentage of share ownership for traversal. Defaults to 0.

        include_unknown_shares : typing.Optional[bool]
            Also traverse relationships when share percentages are unknown. Only useful when min_shares is set greater than 0. Defaults to true.

        exclude_former_relationships : typing.Optional[bool]
            Include relationships that were valid in the past but not at the present time. Defaults to false.

        exclude_closed_entities : typing.Optional[bool]
            Include entities that existed in the past but not at the present time. Defaults to false.

        eu_high_risk_third : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_modern_slavery : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        state_owned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        formerly_sanctioned : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_terrorism : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_organized_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_financial_crime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_bribery_and_corruption : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_other : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        reputational_risk_cybercrime : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        regulatory_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        law_enforcement_action : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        xinjiang_geospatial : typing.Optional[bool]
            Filter paths to only those that entity with an entity that we have flagged with this risk factor

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        TraversalResponse

        Examples
        --------
        import asyncio

        from sayari import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.traversal.watchlist(
                id="mGq1lpuqKssNWTjIokuPeA",
                limit=1,
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            f"v1/watchlist/{jsonable_encoder(id)}",
            method="GET",
            params={
                "limit": limit,
                "offset": offset,
                "min_depth": min_depth,
                "max_depth": max_depth,
                "relationships": relationships,
                "psa": psa,
                "countries": countries,
                "types": types,
                "sanctioned": sanctioned,
                "pep": pep,
                "min_shares": min_shares,
                "include_unknown_shares": include_unknown_shares,
                "exclude_former_relationships": exclude_former_relationships,
                "exclude_closed_entities": exclude_closed_entities,
                "eu_high_risk_third": eu_high_risk_third,
                "reputational_risk_modern_slavery": reputational_risk_modern_slavery,
                "state_owned": state_owned,
                "formerly_sanctioned": formerly_sanctioned,
                "reputational_risk_terrorism": reputational_risk_terrorism,
                "reputational_risk_organized_crime": reputational_risk_organized_crime,
                "reputational_risk_financial_crime": reputational_risk_financial_crime,
                "reputational_risk_bribery_and_corruption": reputational_risk_bribery_and_corruption,
                "reputational_risk_other": reputational_risk_other,
                "reputational_risk_cybercrime": reputational_risk_cybercrime,
                "regulatory_action": regulatory_action,
                "law_enforcement_action": law_enforcement_action,
                "xinjiang_geospatial": xinjiang_geospatial,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    TraversalResponse,
                    parse_obj_as(
                        type_=TraversalResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)

    async def shortest_path(
        self,
        *,
        entities: typing.Union[str, typing.Sequence[str]],
        request_options: typing.Optional[RequestOptions] = None,
    ) -> ShortestPathResponse:
        """
        The Shortest Path endpoint returns a response identifying the shortest traversal path connecting each pair of entities.

        Parameters
        ----------
        entities : typing.Union[str, typing.Sequence[str]]
            A list of Sayari entity IDs specifying the source and target entities for the shortest path calculation. The list must contain exactly two entity IDs The first entity ID represents the source.The second entity ID represents the target.

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        ShortestPathResponse

        Examples
        --------
        import asyncio

        from sayari import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )


        async def main() -> None:
            await client.traversal.shortest_path(
                entities="H1y25N5ymnFyZ-q9Lpwm_g&entities=xthsA_jQuKn3GW8-9ILQqg",
            )


        asyncio.run(main())
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/shortest_path",
            method="GET",
            params={
                "entities": entities,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                return typing.cast(
                    ShortestPathResponse,
                    parse_obj_as(
                        type_=ShortestPathResponse,  # type: ignore
                        object_=_response.json(),
                    ),
                )
            if _response.status_code == 400:
                raise BadRequest(
                    typing.cast(
                        BadRequestResponse,
                        parse_obj_as(
                            type_=BadRequestResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 401:
                raise Unauthorized(
                    typing.cast(
                        UnauthorizedResponse,
                        parse_obj_as(
                            type_=UnauthorizedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 404:
                raise NotFound(
                    typing.cast(
                        NotFoundResponse,
                        parse_obj_as(
                            type_=NotFoundResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 405:
                raise MethodNotAllowed(
                    typing.cast(
                        MethodNotAllowedResponse,
                        parse_obj_as(
                            type_=MethodNotAllowedResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 429:
                raise RateLimitExceeded(
                    typing.cast(
                        RateLimitResponse,
                        parse_obj_as(
                            type_=RateLimitResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 500:
                raise InternalServerError(
                    typing.cast(
                        InternalServerErrorResponse,
                        parse_obj_as(
                            type_=InternalServerErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 502:
                raise BadGateway(
                    typing.cast(
                        BadGatewayResponse,
                        parse_obj_as(
                            type_=BadGatewayResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            if _response.status_code == 520:
                raise ConnectionError(
                    typing.cast(
                        ConnectionErrorResponse,
                        parse_obj_as(
                            type_=ConnectionErrorResponse,  # type: ignore
                            object_=_response.json(),
                        ),
                    )
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, body=_response.text)
        raise ApiError(status_code=_response.status_code, body=_response_json)
