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

import typing
import urllib.parse
from json.decoder import JSONDecodeError

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


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.client 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(
            method="GET",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v1/traversal/{jsonable_encoder(id)}"),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "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.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(TraversalResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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_owner, 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.client 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(
            method="GET",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v1/ubo/{jsonable_encoder(id)}"),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "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.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(TraversalResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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, owner_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.client 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(
            method="GET",
            url=urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v1/downstream/{jsonable_encoder(id)}"
            ),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "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.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(TraversalResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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.client 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(
            method="GET",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v1/watchlist/{jsonable_encoder(id)}"),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "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.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(TraversalResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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]]

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

        Returns
        -------
        ShortestPathResponse

        Examples
        --------
        from sayari.client import Sayari

        client = Sayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        client.traversal.shortest_path(
            entities="string",
        )
        """
        _response = self._client_wrapper.httpx_client.request(
            method="GET",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v1/shortest_path"),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "entities": entities,
                            **(
                                request_options.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(ShortestPathResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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
        --------
        from sayari.client import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.traversal.traversal(
            id="mGq1lpuqKssNWTjIokuPeA",
            limit=1,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            method="GET",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v1/traversal/{jsonable_encoder(id)}"),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "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.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(TraversalResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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_owner, 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.client import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.traversal.ubo(
            id="mGq1lpuqKssNWTjIokuPeA",
            limit=1,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            method="GET",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v1/ubo/{jsonable_encoder(id)}"),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "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.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(TraversalResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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, owner_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.client import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.traversal.ownership(
            id="mGq1lpuqKssNWTjIokuPeA",
            limit=1,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            method="GET",
            url=urllib.parse.urljoin(
                f"{self._client_wrapper.get_base_url()}/", f"v1/downstream/{jsonable_encoder(id)}"
            ),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "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.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(TraversalResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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
        --------
        from sayari.client import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.traversal.watchlist(
            id="mGq1lpuqKssNWTjIokuPeA",
            limit=1,
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            method="GET",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", f"v1/watchlist/{jsonable_encoder(id)}"),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "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.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(TraversalResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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]]

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

        Returns
        -------
        ShortestPathResponse

        Examples
        --------
        from sayari.client import AsyncSayari

        client = AsyncSayari(
            client_id="YOUR_CLIENT_ID",
            client_secret="YOUR_CLIENT_SECRET",
        )
        await client.traversal.shortest_path(
            entities="string",
        )
        """
        _response = await self._client_wrapper.httpx_client.request(
            method="GET",
            url=urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "v1/shortest_path"),
            params=encode_query(
                jsonable_encoder(
                    remove_none_from_dict(
                        {
                            "entities": entities,
                            **(
                                request_options.get("additional_query_parameters", {})
                                if request_options is not None
                                else {}
                            ),
                        }
                    )
                )
            ),
            headers=jsonable_encoder(
                remove_none_from_dict(
                    {
                        **self._client_wrapper.get_headers(),
                        **(request_options.get("additional_headers", {}) if request_options is not None else {}),
                    }
                )
            ),
            timeout=request_options.get("timeout_in_seconds")
            if request_options is not None and request_options.get("timeout_in_seconds") is not None
            else self._client_wrapper.get_timeout(),
            retries=0,
            max_retries=request_options.get("max_retries") if request_options is not None else 0,  # type: ignore
        )
        if 200 <= _response.status_code < 300:
            return pydantic_v1.parse_obj_as(ShortestPathResponse, _response.json())  # type: ignore
        if _response.status_code == 400:
            raise BadRequest(pydantic_v1.parse_obj_as(BadRequestResponse, _response.json()))  # type: ignore
        if _response.status_code == 401:
            raise Unauthorized(pydantic_v1.parse_obj_as(UnauthorizedResponse, _response.json()))  # type: ignore
        if _response.status_code == 404:
            raise NotFound(pydantic_v1.parse_obj_as(NotFoundResponse, _response.json()))  # type: ignore
        if _response.status_code == 405:
            raise MethodNotAllowed(pydantic_v1.parse_obj_as(MethodNotAllowedResponse, _response.json()))  # type: ignore
        if _response.status_code == 429:
            raise RateLimitExceeded(pydantic_v1.parse_obj_as(RateLimitResponse, _response.json()))  # type: ignore
        if _response.status_code == 500:
            raise InternalServerError(
                pydantic_v1.parse_obj_as(InternalServerErrorResponse, _response.json())  # type: ignore
            )
        if _response.status_code == 502:
            raise BadGateway(pydantic_v1.parse_obj_as(BadGatewayResponse, _response.json()))  # type: ignore
        if _response.status_code == 520:
            raise ConnectionError(pydantic_v1.parse_obj_as(ConnectionErrorResponse, _response.json()))  # type: ignore
        try:
            _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)
