From c5789b776665307c5efc106ed6729ef1e53b8b82 Mon Sep 17 00:00:00 2001 From: David Hoese <david.hoese@ssec.wisc.edu> Date: Sun, 26 Feb 2023 14:38:07 -0600 Subject: [PATCH] Reduce complex of data API functions --- metobsapi/data_api.py | 70 +++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/metobsapi/data_api.py b/metobsapi/data_api.py index cf43c86..81e1e08 100644 --- a/metobsapi/data_api.py +++ b/metobsapi/data_api.py @@ -43,6 +43,8 @@ def handle_date(date): def handle_time_string(date_string): + if not date_string: + return None if date_string[0] == "-": times = [float(x) for x in date_string[1:].split(":")] diff = timedelta(hours=times[0], minutes=times[1], seconds=times[2]) @@ -291,25 +293,46 @@ RESPONSE_HANDLERS = { def modify_data(fmt, begin, end, site, inst, symbols, interval, sep=",", order="columns", epoch=None): if fmt not in RESPONSE_HANDLERS: return render_template("400.html", format=fmt), 400 + if not interval: + interval = "1m" + + try: + begin, end = _convert_begin_and_end(begin, end) + _check_query_parameters(order, epoch, symbols, interval) + short_symbols, symbols = _parse_symbol_names(site, inst, symbols) + influx_symbols = handle_symbols(symbols) + except ValueError as e: + return handle_error(fmt, str(e)) + + result, response_info = _query_time_series_db(begin, end, interval, influx_symbols, epoch) + frame = handle_influxdb_result(result, influx_symbols, interval) + frame = _reorder_and_rename_result_dataframe(frame, symbols, short_symbols) + handler = RESPONSE_HANDLERS[fmt] + return handler(frame, epoch, sep=sep, order=order, **response_info) + +def _convert_begin_and_end(begin, end) -> tuple[datetime | timedelta, datetime | timedelta]: try: # these will be either datetime or timedelta objects - begin = handle_time_string(begin) if begin else None - end = handle_time_string(end) if end else None + begin = handle_time_string(begin) + end = handle_time_string(end) except (TypeError, ValueError): - return handle_error(fmt, "malformed_timestamp") + raise ValueError("malformed_timestamp") + return begin, end + +def _check_query_parameters(order, epoch, symbols, interval): if order not in ("column", "row"): - return handle_error(fmt, "bad_order") + raise ValueError("bad_order") if epoch and epoch not in data_responses.epoch_translation: - return handle_error(fmt, "bad_epoch") + raise ValueError("bad_epoch") if not symbols: - return handle_error(fmt, "missing_symbols") - if not interval: - interval = "1m" - elif interval not in data_responses.INTERVALS: - return handle_error(fmt, "bad_interval") + raise ValueError("missing_symbols") + if interval not in data_responses.INTERVALS: + raise ValueError("bad_interval") + +def _parse_symbol_names(site, inst, symbols): if site and inst: # shorthand for symbols that all use the same site and inst short_symbols = symbols.split(":") @@ -319,13 +342,11 @@ def modify_data(fmt, begin, end, site, inst, symbols, interval, sep=",", order=" short_symbols = None symbols = symbols.split(":") else: - return handle_error(fmt, "missing_site_inst") + raise ValueError("missing_site_inst") + return short_symbols, symbols - try: - influx_symbols = handle_symbols(symbols) - except ValueError as e: - return handle_error(fmt, str(e)) +def _query_time_series_db(begin, end, interval, influx_symbols, epoch): if calc_num_records(begin, end, interval) > data_responses.RESPONSES_LIMIT: message = "Request will return too many values, please use files API" code = 413 @@ -337,13 +358,18 @@ def modify_data(fmt, begin, end, site, inst, symbols, interval, sep=",", order=" status = "success" queries = build_queries(influx_symbols, begin, end, interval) result = query(queries, epoch) + response_info = {"message": message, "code": code, "status": status} + return result, response_info - frame = handle_influxdb_result(result, influx_symbols, interval) + +def _reorder_and_rename_result_dataframe( + frame: pd.DataFrame, + ordered_symbols: list[str], + new_symbol_names: list[str], +) -> pd.DataFrame: # order the resulting symbols the way the user requested # assume time is the first column - frame = frame[symbols] - if site: - frame.columns = short_symbols - - handler = RESPONSE_HANDLERS[fmt] - return handler(frame, epoch, sep=sep, order=order, status=status, code=code, message=message) + frame = frame[ordered_symbols] + if new_symbol_names is not None: + frame.columns = new_symbol_names + return frame -- GitLab