Return a location point by address.

        :param str query: The address or query you wish to geocode.

            For a structured query, provide a dictionary whose keys
            are one of: `country`, `state`, `city`, `zipcode`, `street`, `address`,
            `houseNumber` or `subNumber`.

        :param country_codes: Provides the geocoder with a list
            of country codes that the query may reside in. This value will
            limit the geocoder to the supplied countries. The country code
            is a 2 character code as defined by the ISO-3166-1 alpha-2
            standard (e.g. ``FR``). Multiple countries can be specified with
            a Python list.

            .. versionchanged:: 1.19.0
                Previously only a Python list of countries could be specified.
                Now a single country as a string can be specified as well.

        :type country_codes: str or list

        :param bool exactly_one: Return one result or a list of one result.

        :param int timeout: Time, in seconds, to wait for the geocoding service
            to respond before raising a :class:`geopy.exc.GeocoderTimedOut`
            exception. Set this only if you wish to override, on this call
            only, the value set during the geocoder's initialization.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.

def geocode(
            self,
            query,
            country_codes=None,
            exactly_one=True,
            timeout=DEFAULT_SENTINEL,
    ):
        """
        Return a location point by address.

        :param str query: The address or query you wish to geocode.

            For a structured query, provide a dictionary whose keys
            are one of: `country`, `state`, `city`, `zipcode`, `street`, `address`,
            `houseNumber` or `subNumber`.

        :param country_codes: Provides the geocoder with a list
            of country codes that the query may reside in. This value will
            limit the geocoder to the supplied countries. The country code
            is a 2 character code as defined by the ISO-3166-1 alpha-2
            standard (e.g. ``FR``). Multiple countries can be specified with
            a Python list.

            .. versionchanged:: 1.19.0
                Previously only a Python list of countries could be specified.
                Now a single country as a string can be specified as well.

        :type country_codes: str or list

        :param bool exactly_one: Return one result or a list of one result.

        :param int timeout: Time, in seconds, to wait for the geocoding service
            to respond before raising a :class:`geopy.exc.GeocoderTimedOut`
            exception. Set this only if you wish to override, on this call
            only, the value set during the geocoder's initialization.

        :rtype: ``None``, :class:`geopy.location.Location` or a list of them, if
            ``exactly_one=False``.

        """

        if isinstance(query, dict):
            params = {
                key: val
                for key, val
                in query.items()
                if key in self.structured_query_params
            }
            params['api_key'] = self.api_key
        else:
            params = {
                'api_key': self.api_key,
                'q': self.format_string % query,
            }

        if not country_codes:
            country_codes = []
        if isinstance(country_codes, string_compare):
            country_codes = [country_codes]
        if country_codes:
            params['countryCodes'] = ",".join(country_codes)

        url = "?".join((self.api, urlencode(params)))

        logger.debug("%s.geocode: %s", self.__class__.__name__, url)
        return self._parse_json(
            self._call_geocoder(url, timeout=timeout), exactly_one
        )