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

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

import httpx
import pydantic

from .core.api_error import ApiError
from .core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from .core.remove_none_from_dict import remove_none_from_dict
from .environment import GroTradeFlowEnvironment
from .errors.bad_request_error import BadRequestError
from .errors.not_found_error import NotFoundError
from .resources.fern.client import AsyncFernClient, FernClient


class GroTradeFlow:
    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: GroTradeFlowEnvironment = GroTradeFlowEnvironment.PRODUCTION,
        timeout: typing.Optional[float] = 60,
    ):
        self._client_wrapper = SyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            httpx_client=httpx.Client(timeout=timeout),
        )
        self.fern = FernClient(client_wrapper=self._client_wrapper)

    def list_countries(self, *, freq: str) -> typing.List[str]:
        """
        Retrieve a list of countries. Input is a frequency [M, Q, A] and output is a list of countries that have data for that frequency.

        Parameters:
            - freq: str.
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/list_countries"),
            params=remove_none_from_dict({"freq": freq}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[str], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 list_items(
        self, *, country: str, freq: str, partner_region: typing.Optional[str] = None
    ) -> typing.List[typing.Dict[str, str]]:
        """
        Retrieve a list of items. Input is a frequency [M, Q, A] and a country and output is a list of items that have data for that frequency.

        Parameters:
            - country: str.

            - freq: str.

            - partner_region: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/list_items"),
            params=remove_none_from_dict({"country": country, "freq": freq, "partner_region": partner_region}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[typing.Dict[str, str]], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_import_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Retrieve trade flow import data for a given country and item or HS code. Required parameters are country and item or HS code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_import_value"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_export_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Retrieve trade flow data export for a given country and item or HS code. Required parameters are country and item or HS code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_export_value"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_import_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Retrieve import volume trade flow data for a given country and item or HS code. Required parameters are country and item or HS code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_import_volume"),
            params=remove_none_from_dict(
                {"country": country, "item": item, "hs_code": hs_code, "partner_region": partner_region, "freq": freq}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_export_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Retrieve export volume trade flow data for a given country and item or HS code. Required parameters are country and item or HS code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_export_volume"),
            params=remove_none_from_dict(
                {"country": country, "item": item, "hs_code": hs_code, "partner_region": partner_region, "freq": freq}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_all_for_time(
        self,
        *,
        metric: str,
        year: str,
        month: typing.Optional[str] = None,
        quarter: typing.Optional[str] = None,
        item: typing.Union[typing.Optional[str], typing.List[str]],
        hs_code: typing.Union[typing.Optional[str], typing.List[str]],
        country: typing.Union[typing.Optional[str], typing.List[str]],
        partner_region: typing.Union[typing.Optional[str], typing.List[str]],
        in_usd: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get all items data for a particular country or all countries for a particular item in a single time period. Required parameters are metric, year, and country or item/hs_code. Optional parameters are month, quarter, partner_region, and in_usd.

        Parameters:
            - metric: str.

            - year: str.

            - month: typing.Optional[str].

            - quarter: typing.Optional[str].

            - item: typing.Union[typing.Optional[str], typing.List[str]].

            - hs_code: typing.Union[typing.Optional[str], typing.List[str]].

            - country: typing.Union[typing.Optional[str], typing.List[str]].

            - partner_region: typing.Union[typing.Optional[str], typing.List[str]].

            - in_usd: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_all_for_time"),
            params=remove_none_from_dict(
                {
                    "metric": metric,
                    "year": year,
                    "month": month,
                    "quarter": quarter,
                    "item": item,
                    "hs_code": hs_code,
                    "country": country,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_implied_import_prices(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get implied import prices for a particular country and item or HS code. Required parameters are country and item/hs_code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_implied_import_prices"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_implied_export_prices(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get implied import prices for a particular country and item or HS code. Required parameters are country and item/hs_code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_implied_export_prices"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 aggregate_balance_of_trade(
        self,
        *,
        country: str,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get aggregate balance of trade for a particular country. Required parameter is country. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/aggregate_balance_of_trade"),
            params=remove_none_from_dict(
                {"country": country, "partner_region": partner_region, "in_usd": in_usd, "freq": freq}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_net_export_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get net export value for a particular country. Required parameter is country. Optional parameters are item, partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_net_export_value"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_net_export_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get net export volume for a particular country. Required parameter is country. Optional parameters are item, partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_net_export_volume"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 AsyncGroTradeFlow:
    def __init__(
        self,
        *,
        base_url: typing.Optional[str] = None,
        environment: GroTradeFlowEnvironment = GroTradeFlowEnvironment.PRODUCTION,
        timeout: typing.Optional[float] = 60,
    ):
        self._client_wrapper = AsyncClientWrapper(
            base_url=_get_base_url(base_url=base_url, environment=environment),
            httpx_client=httpx.AsyncClient(timeout=timeout),
        )
        self.fern = AsyncFernClient(client_wrapper=self._client_wrapper)

    async def list_countries(self, *, freq: str) -> typing.List[str]:
        """
        Retrieve a list of countries. Input is a frequency [M, Q, A] and output is a list of countries that have data for that frequency.

        Parameters:
            - freq: str.
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/list_countries"),
            params=remove_none_from_dict({"freq": freq}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[str], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 list_items(
        self, *, country: str, freq: str, partner_region: typing.Optional[str] = None
    ) -> typing.List[typing.Dict[str, str]]:
        """
        Retrieve a list of items. Input is a frequency [M, Q, A] and a country and output is a list of items that have data for that frequency.

        Parameters:
            - country: str.

            - freq: str.

            - partner_region: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/list_items"),
            params=remove_none_from_dict({"country": country, "freq": freq, "partner_region": partner_region}),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.List[typing.Dict[str, str]], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_import_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Retrieve trade flow import data for a given country and item or HS code. Required parameters are country and item or HS code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_import_value"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_export_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Retrieve trade flow data export for a given country and item or HS code. Required parameters are country and item or HS code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_export_value"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_import_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Retrieve import volume trade flow data for a given country and item or HS code. Required parameters are country and item or HS code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_import_volume"),
            params=remove_none_from_dict(
                {"country": country, "item": item, "hs_code": hs_code, "partner_region": partner_region, "freq": freq}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_export_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        Retrieve export volume trade flow data for a given country and item or HS code. Required parameters are country and item or HS code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_export_volume"),
            params=remove_none_from_dict(
                {"country": country, "item": item, "hs_code": hs_code, "partner_region": partner_region, "freq": freq}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_all_for_time(
        self,
        *,
        metric: str,
        year: str,
        month: typing.Optional[str] = None,
        quarter: typing.Optional[str] = None,
        item: typing.Union[typing.Optional[str], typing.List[str]],
        hs_code: typing.Union[typing.Optional[str], typing.List[str]],
        country: typing.Union[typing.Optional[str], typing.List[str]],
        partner_region: typing.Union[typing.Optional[str], typing.List[str]],
        in_usd: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get all items data for a particular country or all countries for a particular item in a single time period. Required parameters are metric, year, and country or item/hs_code. Optional parameters are month, quarter, partner_region, and in_usd.

        Parameters:
            - metric: str.

            - year: str.

            - month: typing.Optional[str].

            - quarter: typing.Optional[str].

            - item: typing.Union[typing.Optional[str], typing.List[str]].

            - hs_code: typing.Union[typing.Optional[str], typing.List[str]].

            - country: typing.Union[typing.Optional[str], typing.List[str]].

            - partner_region: typing.Union[typing.Optional[str], typing.List[str]].

            - in_usd: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_all_for_time"),
            params=remove_none_from_dict(
                {
                    "metric": metric,
                    "year": year,
                    "month": month,
                    "quarter": quarter,
                    "item": item,
                    "hs_code": hs_code,
                    "country": country,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_implied_import_prices(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get implied import prices for a particular country and item or HS code. Required parameters are country and item/hs_code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_implied_import_prices"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_implied_export_prices(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get implied import prices for a particular country and item or HS code. Required parameters are country and item/hs_code. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_implied_export_prices"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 aggregate_balance_of_trade(
        self,
        *,
        country: str,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get aggregate balance of trade for a particular country. Required parameter is country. Optional parameters are partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/aggregate_balance_of_trade"),
            params=remove_none_from_dict(
                {"country": country, "partner_region": partner_region, "in_usd": in_usd, "freq": freq}
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_net_export_value(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get net export value for a particular country. Required parameter is country. Optional parameters are item, partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_net_export_value"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 get_net_export_volume(
        self,
        *,
        country: str,
        item: typing.Optional[str] = None,
        hs_code: typing.Optional[str] = None,
        partner_region: typing.Optional[str] = None,
        in_usd: typing.Optional[str] = None,
        freq: typing.Optional[str] = None,
    ) -> typing.Dict[str, typing.Any]:
        """
        get net export volume for a particular country. Required parameter is country. Optional parameters are item, partner_region, in_usd, and freq.

        Parameters:
            - country: str.

            - item: typing.Optional[str].

            - hs_code: typing.Optional[str].

            - partner_region: typing.Optional[str].

            - in_usd: typing.Optional[str].

            - freq: typing.Optional[str].
        """
        _response = await self._client_wrapper.httpx_client.request(
            "GET",
            urllib.parse.urljoin(f"{self._client_wrapper.get_base_url()}/", "trade-flows/get_net_export_volume"),
            params=remove_none_from_dict(
                {
                    "country": country,
                    "item": item,
                    "hs_code": hs_code,
                    "partner_region": partner_region,
                    "in_usd": in_usd,
                    "freq": freq,
                }
            ),
            headers=self._client_wrapper.get_headers(),
            timeout=60,
        )
        if 200 <= _response.status_code < 300:
            return pydantic.parse_obj_as(typing.Dict[str, typing.Any], _response.json())  # type: ignore
        if _response.status_code == 404:
            raise NotFoundError(pydantic.parse_obj_as(str, _response.json()))  # type: ignore
        if _response.status_code == 400:
            raise BadRequestError(pydantic.parse_obj_as(str, _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 _get_base_url(*, base_url: typing.Optional[str] = None, environment: GroTradeFlowEnvironment) -> str:
    if base_url is not None:
        return base_url
    elif environment is not None:
        return environment.value
    else:
        raise Exception("Please pass in either base_url or environment to construct the client")
