Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Breaking Change]: Remove save file func #159

Merged
merged 10 commits into from
May 25, 2022
112 changes: 12 additions & 100 deletions src/ozone/ozone.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
RATE_LIMIT (int=1): The time period in seconds for the max number of calls is
1 second.
"""

import itertools
import json
import warnings
Expand Down Expand Up @@ -50,10 +49,7 @@ class Ozone:

Attributes:
token (str): The private API token for the WAQI API service.
output_dir_path (str): The path to the directory where
any output artifacts will be created
"""

_search_aqi_url: str = URLs.search_aqi_url
_find_stations_url: str = URLs.find_stations_url
_default_params: List[str] = [
Expand All @@ -79,22 +75,10 @@ def __init__(

Args:
token (str): The users private API token for the WAQI API.
output_path (str): The path to the location where
any output artifacts will be created
file_name (str): Name of output file
"""
self.token: str = token
self._check_token_validity()

self.output_dir_path: Path = Path(output_path, "ozone_output")
self.file_name = file_name

if self.file_name == "air_quality":
warnings.warn(
"You have not specified a custom save file name. "
"Existing files with the same name may be overwritten!"
)

def _check_token_validity(self) -> None:
"""Check if the token is valid"""
test_city: str = "london"
Expand Down Expand Up @@ -142,52 +126,6 @@ def reset_token(self, token: str) -> None:
self.token = token
self._check_token_validity()

def _format_output(
self,
data_format: str = "df",
df: pandas.DataFrame = pandas.DataFrame(),
) -> pandas.DataFrame:
"""Format output data

Args:
data_format (str): File format. Defaults to 'df'.
Choose from 'csv', 'json', 'xlsx'.
df (pandas.DataFrame,): Dataframe object of air quality data.

Returns:
pandas.DataFrame: The dataframe containing the air quality data.
None: print the string response of file type created.
"""
if data_format == "df":
return df

if data_format not in ["csv", "xlsx", "json"]:
raise Exception(
f"Invalid file format {data_format}. Use any of: csv, json, xlsx, df"
)

self.output_dir_path.mkdir(exist_ok=True)

if data_format == "csv":
df.to_csv(Path(self.output_dir_path, f"{self.file_name}.csv"), index=False)
print(
f"File saved to disk at {self.output_dir_path} as {self.file_name}.csv"
)
elif data_format == "json":
df.to_json(Path(self.output_dir_path, f"{self.file_name}.json"))
print(
f"File saved to disk at {self.output_dir_path} as {self.file_name}.json"
)
elif data_format == "xlsx":
df.to_excel(
Path(self.output_dir_path, f"{self.file_name}.xlsx"),
)
print(
f"File saved to disk at {self.output_dir_path} as {self.file_name}.xlsx"
)

return pandas.DataFrame()

def _extract_live_data(
self, data_obj: Any, params: List[str] = [""]
) -> Dict[str, Union[str, float]]:
Expand Down Expand Up @@ -410,7 +348,6 @@ def get_coordinate_air(
self,
lat: float,
lon: float,
data_format: str = "df",
df: pandas.DataFrame = pandas.DataFrame(),
params: List[str] = [""],
) -> pandas.DataFrame:
Expand All @@ -419,8 +356,6 @@ def get_coordinate_air(
Args:
lat (float): Latitude
lon (float): Longitude
data_format (str): File format for data. Defaults to 'df'.
Choose from 'csv', 'json', 'xlsx'.
df (pandas.DataFrame, optional): An existing dataframe to
append the data to.
params (List[str], optional): A list of parameters to get data for.
Expand All @@ -431,7 +366,6 @@ def get_coordinate_air(

Returns:
pandas.DataFrame: The dataframe containing the data.
(If you selected another data format, this dataframe will be empty)
"""
if params == [""]:
params = self._default_params
Expand All @@ -443,21 +377,18 @@ def get_coordinate_air(

row = self._extract_live_data(data_obj, params=params)
df = pandas.concat([df, pandas.DataFrame([row])], ignore_index=True)
return self._format_output(data_format, df)
return df

def get_city_air(
self,
city: str,
data_format: str = "df",
df: pandas.DataFrame = pandas.DataFrame(),
params: List[str] = [""],
) -> pandas.DataFrame:
"""Get a city's air quality data

Args:
city (str): The city to get data for.
data_format (str): File format for data. Defaults to 'df'.
Choose from 'csv', 'json', 'xlsx'.
df (pandas.DataFrame, optional): An existing dataframe to
append the data to.
params (List[str], optional): A list of parameters to get data for.
Expand All @@ -468,7 +399,6 @@ def get_city_air(

Returns:
pandas.DataFrame: The dataframe containing the data.
(If you selected another data format, this dataframe will be empty)
"""
if params == [""]:
params = self._default_params
Expand All @@ -480,21 +410,18 @@ def get_city_air(
row["city"] = city

df = pandas.concat([df, pandas.DataFrame([row])], ignore_index=True)
return self._format_output(data_format, df)
return df

def get_multiple_coordinate_air(
self,
locations: List[Tuple],
data_format: str = "df",
df: pandas.DataFrame = pandas.DataFrame(),
params: List[str] = [""],
) -> pandas.DataFrame:
"""Get multiple locations air quality data

Args:
locations (list): A list of pair (latitude,longitude) to get data for.
data_format (str): File format. Defaults to 'df'.
Choose from 'csv', 'json', 'xlsx'.
df (pandas.DataFrame, optional): An existing dataframe to
append the data to.
params (List[str], optional): A list of parameters to get data for.
Expand All @@ -504,8 +431,7 @@ def get_multiple_coordinate_air(
Gets all parameters by default..

Returns:
pandas.DataFrame: The dataframe containing the data. (If you
selected another data format, this dataframe will be empty)
pandas.DataFrame: The dataframe containing the data.
"""
for loc in locations:
try:
Expand All @@ -522,13 +448,12 @@ def get_multiple_coordinate_air(
df = pandas.concat([df, empty_row], ignore_index=True)

df.reset_index(inplace=True, drop=True)
return self._format_output(data_format, df)
return df

def get_range_coordinates_air(
self,
lower_bound: Tuple[float, float],
upper_bound: Tuple[float, float],
data_format: str = "df",
df: pandas.DataFrame = pandas.DataFrame(),
params: List[str] = [""],
) -> pandas.DataFrame:
Expand All @@ -537,8 +462,6 @@ def get_range_coordinates_air(
Args:
lower_bound (tuple): start coordinate
upper_bound (tuple): end coordinate
data_format (str): File format. Defaults to 'df'.
Choose from 'csv', 'json', 'xlsx'.
df (pandas.DataFrame, optional): An existing dataframe to
append the data to.
params (List[str], optional): A list of parameters to get data for.
Expand All @@ -548,29 +471,25 @@ def get_range_coordinates_air(
Gets all parameters by default.

Returns:
pandas.DataFrame: The dataframe containing the data. (If you
selected another data format, this dataframe will be empty)
pandas.DataFrame: The dataframe containing the data.
"""
locations = self._locate_all_coordinates(
lower_bound=lower_bound, upper_bound=upper_bound
)
return self.get_multiple_coordinate_air(
locations, data_format=data_format, df=df, params=params
locations, df=df, params=params
)

def get_multiple_city_air(
self,
cities: List[str],
data_format: str = "df",
df: pandas.DataFrame = pandas.DataFrame(),
params: List[str] = [""],
) -> pandas.DataFrame:
"""Get multiple cities' air quality data

Args:
cities (list): A list of cities to get data for.
data_format (str): File format. Defaults to 'df'.
Choose from 'csv', 'json', 'xlsx'.
params (List[str], optional): A list of parameters to get data for.
Choose from the following values:
["aqi", "pm2.5", "pm10", "o3", "co", "no2", "so2", "dew", "h",
Expand All @@ -580,8 +499,7 @@ def get_multiple_city_air(
append the data to.

Returns:
pandas.DataFrame: The dataframe containing the data. (If you
selected another data format, this dataframe will be empty)
pandas.DataFrame: The dataframe containing the data.
"""
for city in cities:
try:
Expand All @@ -596,7 +514,7 @@ def get_multiple_city_air(
df = pandas.concat([df, empty_row], ignore_index=True)

df.reset_index(inplace=True, drop=True)
return self._format_output(data_format, df)
return df

def get_specific_parameter(
self,
Expand Down Expand Up @@ -638,7 +556,6 @@ def get_city_station_options(self, city: str) -> pandas.DataFrame:

Returns:
pandas.DataFrame: Table of stations and their relevant information.

"""
# NOTE, HACK, FIXME:
# This functionality was born together with historical data feature.
Expand Down Expand Up @@ -669,13 +586,11 @@ def get_city_station_options(self, city: str) -> pandas.DataFrame:
).sort_values(by=["score"], ascending=False)

def get_historical_data(
self, data_format: str = "df", *, city: str = None, city_id: int = None
self, city: str = None, city_id: int = None
) -> pandas.DataFrame:
"""Get historical air quality data for a city

Args:
data_format (str): File format. Defaults to 'df'.
Choose from 'csv', 'json', 'xlsx'.
city (str): Name of the city. If given, the argument must be named.
city_id (int): City ID. If given, the argument must be named.
If not given, city argument must not be None.
Expand Down Expand Up @@ -725,26 +640,23 @@ def get_historical_data(
# Reset date index and rename the column appropriately
df = df.reset_index().rename(columns={"index": "date"})

return self._format_output(data_format, df)
return df

def get_city_forecast(
self,
city: str,
data_format: str = "df",
df: pandas.DataFrame = pandas.DataFrame(),
) -> pandas.DataFrame:
"""Get a city's air quality forecast

Args:
city (str): The city to get data for.
data_format (str): File format for data. Defaults to 'df'.
Choose from 'csv', 'json', 'xlsx'.
df (pandas.DataFrame, optional): An existing dataframe to
append the data to.

Returns:
pandas.DataFrame: The dataframe containing the data.
(If you selected another data format, this dataframe will be empty)"""
"""
r = self._make_api_request(f"{self._search_aqi_url}/{city}/?token={self.token}")
data_obj = self._check_and_get_data_obj(r)

Expand All @@ -753,7 +665,7 @@ def get_city_forecast(
# This ensures that pm25 data is labelled correctly.
df.rename(columns={"pm25": "pm2.5"}, inplace=True)

return self._format_output(data_format, df)
return df


if __name__ == "__main__":
Expand Down
10 changes: 5 additions & 5 deletions tests/cassettes/test_get_city_air/test_bad_city.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ interactions:
Content-Length:
- '0'
Date:
- Tue, 03 May 2022 16:48:36 GMT
- Mon, 23 May 2022 07:09:36 GMT
Location:
- /feed/a%20definitely%20nonexistent%20city/?token=DUMMY_TOKEN
Server:
Expand Down Expand Up @@ -53,15 +53,15 @@ interactions:
Content-Type:
- application/json; charset=UTF-8
Date:
- Tue, 03 May 2022 16:48:36 GMT
- Mon, 23 May 2022 07:09:36 GMT
Server:
- nginx
Transfer-Encoding:
- chunked
Vary:
- Accept-Encoding
X-Gen-Time:
- "141.773\xC2\xB5s"
- "119.402\xC2\xB5s"
X-Powered-By:
- rxstreamer-waqi/1.3
content-length:
Expand Down Expand Up @@ -91,7 +91,7 @@ interactions:
Content-Length:
- '0'
Date:
- Tue, 03 May 2022 16:48:36 GMT
- Mon, 23 May 2022 07:09:37 GMT
Location:
- /feed/?token=DUMMY_TOKEN
Server:
Expand Down Expand Up @@ -123,7 +123,7 @@ interactions:
Content-Type:
- application/json; charset=UTF-8
Date:
- Tue, 03 May 2022 16:48:36 GMT
- Mon, 23 May 2022 07:09:37 GMT
Server:
- nginx
Transfer-Encoding:
Expand Down
Loading