def test_file_or_text_response_forged_response_format(monkeypatch,
                                                      mock_coordinates,
                                                      mock_dataset,
                                                      mock_response_query):
    # TEST 1: Non-existing ResponseFormat is intercepted by Class
    with pytest.raises(ValueError) as e:
        assert file_or_text_response(mock_dataset,
                                     ResponseFormat("mock_format"), 'knmi',
                                     'pluim', mock_response_query,
                                     [mock_coordinates])
    assert str(
        e.value.args[0]) == "'mock_format' is not a valid ResponseFormat"

    # TEST 2: Forged non-existing ResponseFormat should be intercepted by file_response
    monkeypatch.setattr(api_models, "ResponseFormat", MockResponseFormat)
    with pytest.raises(NotImplementedError) as e:
        assert file_response(mock_dataset,
                             api_models.ResponseFormat.mock_format, "knmi",
                             "pluim", mock_response_query, [mock_coordinates])
    assert str(
        e.value.args[0]
    ) == f"Cannot create file response for the mock_format response format"
    controller = WeatherController()

    ds_hist_day: xr.Dataset = controller.get_weather(source_id='knmi',
                                                     model_id='daggegevens',
                                                     fetch_async=False,
                                                     coords=coords,
                                                     begin=datetime(year=2018,
                                                                    month=1,
                                                                    day=1),
                                                     end=datetime(year=2018,
                                                                  month=1,
                                                                  day=31))

    response_format = ResponseFormat.netcdf4

    converted_weather_data = controller.convert_names_and_units(
        'knmi', 'daggegevens', False, ds_hist_day, OutputUnit.si)

    ret_args = WeatherContentRequestQuery(begin='2018-01-01 00:00',
                                          end='2018-01-31 23:59',
                                          lat=52.1,
                                          lon=5.18,
                                          factors=None)

    response, optional_file_path = serializers.file_or_text_response(
        converted_weather_data, response_format, 'knmi', 'daggegevens',
        ret_args, coords)

    print(response)
    print(optional_file_path)
def test_file_or_text_response_regular(response_format, mock_coordinates,
                                       mock_dataset, mock_response_query):
    assert file_or_text_response(mock_dataset, ResponseFormat(response_format),
                                 'knmi', 'pluim', mock_response_query,
                                 mock_coordinates)
Exemple #4
0
    ds_hist_day: xr.Dataset = controller.get_weather(
        source_id='cds',
        model_id='era5sl',
        fetch_async=False,
        coords=coords,
        begin=datetime(2018, 2, 1, 0, 0),
        end=datetime(2018, 2, 28, 23, 59))

    response_format = ResponseFormat.netcdf4

    converted_weather_data = controller.convert_names_and_units(
        'cds', 'era5sl', False, ds_hist_day, OutputUnit.si)

    ret_args = WeatherContentRequestQuery(begin='2018-01-01 00:00',
                                          end='2018-01-31 23:59',
                                          lat=52.1,
                                          lon=5.18,
                                          factors=None)

    coords = [(
        float(np.mean([single_point[0] for single_point in single_polygon])),
        float(np.mean([single_point[1] for single_point in single_polygon])),
    ) for single_polygon in coords
              ]  # means to match the used coordinates for the request
    response, optional_file_path = serializers.file_or_text_response(
        converted_weather_data, response_format, 'cds', 'era5sl', ret_args,
        coords)

    print(response, optional_file_path)
    ]

    ds_hist_day: xr.Dataset = controller.get_weather(source_id='knmi',
                                                     model_id='waarnemingen',
                                                     fetch_async=False,
                                                     coords=coords,
                                                     begin=datetime(year=2018,
                                                                    month=1,
                                                                    day=1),
                                                     end=datetime(year=2018,
                                                                  month=1,
                                                                  day=31))

    response_format = ResponseFormat.netcdf4

    converted_weather_data = controller.convert_names_and_units(
        'knmi', 'waarnemingen', False, ds_hist_day, OutputUnit.si)

    ret_args = WeatherContentRequestQuery(begin='2018-01-01 00:00',
                                          end='2018-01-31 23:59',
                                          lat=52.1,
                                          lon=5.18,
                                          factors=None)

    response, optional_file_path = serializers.file_or_text_response(
        converted_weather_data, response_format, 'knmi', 'waarnemingen',
        ret_args, coords)

    print(response)
    print(optional_file_path)
Exemple #6
0
async def get_sync_weather(
    source_id: str,
    model_id: str,
    cleanup_tasks: BackgroundTasks,
    ret_args: WeatherContentRequestQuery = Depends(),
    fmt_args: WeatherFormattingRequestQuery = Depends(),
    accept: str = Depends(header_accept_type),
):  # pragma: no cover
    """
    <B>Request weather data for a specific Model using the given settings (location, period, weather factors, e.g.). <BR>
    This data is then formatted as the requested output format (output unit system and file format) before returning the requested data.</B>

    <I>(Please note that as some models are predictive or otherwise restricted in the periods available for requests,
    that sometimes the begin and end values will altered to match these restrictions.)</I>
    """
    """
        An API function that retrieves specific weather data for a specific Weather Model and returns it as the 
        requested output format and units.
    Args:
        source_id:      The Source ID of the Source to request the weather data from.
        model_id:       The Model ID for the Model to request the weather data from.
        cleanup_tasks:  A BackgroundTasks object to hold any pending cleanup tasks for when the data request is 
                        finished.
        ret_args:       A WeatherContentRequestQuery object holding the parameters for the weather data request to
                        use.
        fmt_args:       A WeatherFormattingRequestQuery object holding the parameters for the output format and 
                        units to use.
        accept:         Header type to use for the output file.
                        Rounded to the most likely value using header_accept_type().
    Returns:
        The weather data in the requested format for the requested parameters.
    """
    source_id = source_id.lower()
    model_id = model_id.lower()
    coords = controller.lat_lon_to_coords(ret_args.lat, ret_args.lon)

    begin = parse_datetime(ret_args.begin, raise_errors=True, loc=["query", "begin"])
    end = parse_datetime(
        ret_args.end,
        round_missing_time_up=True,
        raise_errors=True,
        loc=["query", "end"],
    )

    try:
        weather_data = controller.get_weather(
            source_id,
            model_id,
            fetch_async=False,
            coords=coords,
            begin=begin,
            end=end,
            factors=ret_args.factors,
        )
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=e.args[0])

    if weather_data is None:
        raise HTTPException(
            status_code=404, detail="No data was found for the given period"
        )

    response_format = fmt_args.response_format or accept

    converted_weather_data = controller.convert_names_and_units(
        source_id, model_id, False, weather_data, fmt_args.units
    )

    coords = [
        (lat_val, lon_val)
        for (lat_val, lon_val) in zip(
            converted_weather_data.coords["lat"].values,
            converted_weather_data.coords["lon"].values,
        )
    ]

    response, optional_file_path = serializers.file_or_text_response(
        converted_weather_data, response_format, source_id, model_id, ret_args, coords
    )
    cleanup_tasks.add_task(remove_file, optional_file_path)

    return response
Exemple #7
0
async def get_sync_weather(
    source_id: str,
    model_id: str,
    cleanup_tasks: BackgroundTasks,
    ret_args: WeatherContentRequestQuery = Depends(),
    fmt_args: WeatherFormattingRequestQuery = Depends(),
    accept: str = Depends(header_accept_type),
):  # pragma: no cover
    """
        Function to gather data for a specific model using specific settings (location, period, factors, e.g.).
        The function then formats this data into the requested output format (file-format and selected output unit) and
        returns it.
    Args:
        source_id:  The identifier for the chosen source
        model_id:   The identifier for the chosen model
        cleanup_tasks: Holder for background tasks, in get_sync_weather solely used for file cleanup, hence the name
        ret_args:   Contains a WeatherContentRequestQuery item with all of the settings to be used for data collection
        fmt_args:   Contains a WeatherFormattingRequestQuery item with all of the setting to be used for formatting the
                    output
        accept:

    Returns:
        Returns a file in the requested output format, containing any weather data that matched the specifications from
        the WeatherContentRequestQuery.

    """

    # TODO: Append a proper definition of the accept arg
    source_id = source_id.lower()
    model_id = model_id.lower()
    coords = controller.lat_lon_to_coords(ret_args.lat, ret_args.lon)

    begin = parse_datetime(ret_args.begin, raise_errors=True, loc=["query", "begin"])
    end = parse_datetime(
        ret_args.end,
        round_missing_time_up=True,
        raise_errors=True,
        loc=["query", "end"],
    )

    try:
        weather_data = controller.get_weather(
            source_id,
            model_id,
            fetch_async=False,
            coords=coords,
            begin=begin,
            end=end,
            factors=ret_args.factors,
        )
    except FileNotFoundError as e:
        raise HTTPException(status_code=404, detail=e.args[0])

    if weather_data is None:
        raise HTTPException(
            status_code=404, detail="No data was found for the given period"
        )

    response_format = fmt_args.response_format or accept

    converted_weather_data = controller.convert_names_and_units(
        source_id, model_id, False, weather_data, fmt_args.units
    )

    coords = [
        (lat_val, lon_val)
        for (lat_val, lon_val) in zip(
            converted_weather_data.coords["lat"].values,
            converted_weather_data.coords["lon"].values,
        )
    ]

    response, optional_file_path = serializers.file_or_text_response(
        converted_weather_data, response_format, source_id, model_id, ret_args, coords
    )
    cleanup_tasks.add_task(remove_file, optional_file_path)

    return response