def fetch( self, station: str = None, lat: float = None, lon: float = None, timeout: int = 10, ) -> str: """ Fetches a report string from the service """ if station: valid_station(station) elif lat is None or lon is None: raise ValueError("No valid fetch parameters") try: url, params = self._make_url(station, lat, lon) if self.method.lower() == "post": resp = requests.post(url, params=params, data=self._post_data(station)) else: resp = requests.get(url, params) if resp.status_code != 200: raise SourceError( f"{self.__class__.__name__} server returned {resp.status_code}" ) except requests.exceptions.ConnectionError: raise ConnectionError( f"Unable to connect to {self.__class__.__name__} server") report = self._extract(resp.text, station) # This split join replaces all *whitespace elements with a single space if isinstance(report, list): return dedupe(" ".join(r.split()) for r in report) return " ".join(report.split())
def __init__(self, icao: str): # Raises a BadStation error if needed station.valid_station(icao) self.station = icao self.station_info = Station.from_icao(icao) self.service = service.get_service(icao, self.station_info.country)( self.__class__.__name__.lower())
def parse(station: str, report: str, issued: date = None) -> Tuple[MetarData, Units]: """Returns MetarData and Units dataclasses with parsed data and their associated units""" valid_station(station) if not report: return None, None parser = parse_na if uses_na_format(station[:2]) else parse_in return parser(report, issued)
def fetch( self, station: str = None, lat: float = None, lon: float = None, timeout: int = 10, ) -> str: """ Fetches a report string from the service """ if station: valid_station(station) elif lat is None or lon is None: raise ValueError("No valid fetch parameters") try: url, params = self._make_url(station, lat, lon) if self.method.lower() == "post": resp = httpx.post(url, params=params, data=self._post_data(station), timeout=timeout) else: resp = httpx.get(url, params=params, timeout=timeout) if resp.status_code != 200: raise SourceError( f"{self.__class__.__name__} server returned {resp.status_code}" ) except (httpx.ConnectTimeout, httpx.ReadTimeout): raise TimeoutError( f"Timeout from {self.__class__.__name__} server") except gaierror: raise ConnectionError( f"Unable to connect to {self.__class__.__name__} server") report = self._extract(resp.text, station) return self._clean_report(report)
def parse(station: str, report: str) -> (MetarData, Units): """ Returns MetarData and Units dataclasses with parsed data and their associated units """ valid_station(station) if not report: return None, None return parse_na(report) if uses_na_format(station[:2]) else parse_in(report)
def parse(station: str, report: str) -> (TafData, Units): """ Returns TafData and Units dataclasses with parsed data and their associated units """ if not report: return None, None valid_station(station) while len(report) > 3 and report[:4] in ("TAF ", "AMD ", "COR "): report = report[4:] retwx = { "end_time": None, "raw": report, "remarks": None, "start_time": None } report = _core.sanitize_report_string(report) _, station, time = _core.get_station_and_time(report[:20].split()) retwx["station"] = station retwx["time"] = _core.make_timestamp(time) report = report.replace(station, "") if time: report = report.replace(time, "").strip() if uses_na_format(station): use_na = True units = Units(**NA_UNITS) else: use_na = False units = Units(**IN_UNITS) # Find and remove remarks report, retwx["remarks"] = _core.get_taf_remarks(report) # Split and parse each line lines = _core.split_taf(report) parsed_lines = parse_lines(lines, units, use_na) # Perform additional info extract and corrections if parsed_lines: parsed_lines[-1]["other"], retwx["max_temp"], retwx[ "min_temp"] = _core.get_temp_min_and_max(parsed_lines[-1]["other"]) if not (retwx["max_temp"] or retwx["min_temp"]): parsed_lines[0]["other"], retwx["max_temp"], retwx[ "min_temp"] = _core.get_temp_min_and_max( parsed_lines[0]["other"]) # Set start and end times based on the first line start, end = parsed_lines[0]["start_time"], parsed_lines[0]["end_time"] parsed_lines[0]["end_time"] = None retwx["start_time"], retwx["end_time"] = start, end parsed_lines = _core.find_missing_taf_times(parsed_lines, start, end) parsed_lines = _core.get_taf_flight_rules(parsed_lines) # Extract Oceania-specific data if retwx["station"][0] == "A": parsed_lines[-1]["other"], retwx["alts"], retwx[ "temps"] = _core.get_oceania_temp_and_alt( parsed_lines[-1]["other"]) # Convert to dataclass retwx["forecast"] = [TafLineData(**line) for line in parsed_lines] return TafData(**retwx), units
async def async_fetch(self, station: str, wait: bool = True, timeout: int = 10, force: bool = False) -> Optional[str]: """Asynchronously fetch a report string from the source file If wait, this will block if the file is already being updated Can force the service to fetch a new file """ valid_station(station) if wait and self._updating: self._wait_until_updated() if force or self.is_outdated: if not await self.update(wait, timeout): return None with self._file.open() as fin: report = self._extract(station, fin) return report
def __init__(self, station_ident: str): # Raises a BadStation error if needed station.valid_station(station_ident) self.service = service.get_service(station_ident)( self.__class__.__name__.lower()) self.station = station_ident
def __init__(self, icao: str): # Raises a BadStation error if needed valid_station(icao) self.icao = icao self.station = Station.from_icao(icao)