def METHOD_NAME(self, zipcodes):
    """Geocode an iterable list of string zipcodes using Mapbox.
    Returns only those zipcodes that can be successfully geocoded as a list
    of (zipcode, coordinates) tuples, where coordinates are float
    (latitude, longitude) in degrees.
    """
    url = self.mapbox_geocode_url(*zipcodes)
    logger.debug("making request to %s", url)
    request_start_time = time.time()
    rate_limit_timeout = 10 * 60
    while True:
        time_now = time.time()
        if time_now - request_start_time > rate_limit_timeout:
            raise RuntimeError(
                "rate limit timeout {} exceeded".format(rate_limit_timeout)
            )
        response = requests.get(url)
        # Handle rate limiting
        if 429 == response.status_code:
            logger.info(
                "rate limited, url %s, headers: %s", url, response.headers
            )
            sleep_for = 10
            logger.info("sleeping for %s seconds", sleep_for)
            time.sleep(sleep_for)
            continue
        response.raise_for_status()
        result = response.json()
        break
    # Mapbox API returns a single dict for a single query or a list for
    # a bulk query of multiple zipcodes at once.
    if isinstance(result, dict):
        result = [result]
    for item in response.json():
        zipcode = item["query"][0]
        if not item["features"]:
            logger.debug("could not geocode %s", zipcode)
            continue
        feature = item["features"][0]
        if feature.get("place_type") != ["postcode"]:
            logger.warning("zipcode %s geocoded to non-postcode", zipcode)
            continue
        geometry = feature.get("geometry")
        if geometry.get("type") != "Point":
            logger.warning("zipcode %s geocoded to non-point", zipcode)
            continue
        longitude, latitude = geometry["coordinates"]
        logger.debug("geocoded %s to %s, %s", zipcode, latitude, longitude)
        yield zipcode, (latitude, longitude)