diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index ee2af31..b15afbe 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -3,6 +3,7 @@ repos:
rev: 'v0.941' # Use the sha / tag to point at specific version
hooks:
- id: mypy
+ additional_dependencies: ['types-requests', 'types-urllib3']
- repo: https://github.com/psf/black
rev: '22.1.0'
hooks:
diff --git a/README.md b/README.md
index ac27d6e..d8b9911 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,8 @@ I want to make it easy to get your hands on accurate air quality data for your p
[License and TOS](#license-and-terms-of-service)
+[Contributors](#contributors)
+
## Install it here!
```sh
@@ -67,6 +69,22 @@ data = o3.get_multiple_city_air([ARRAY OF CITY NAMES])
![Gif of ozone.get_multiple_city_air()](/src/media/ozone_get_multiple_city_air_updated.gif)
+### Air Quality Parameters
+
+Ozone can fetch the following parameters:
+
+ * `aqi`: air quality index, a measurement of air quality that tells you how clean or polluted the air is
+ * `pm25`: fine particulate matter, a measure of 2.5 micrometers or smaller particles in the air
+ * `pm10`: respirable particulate matter, a measure of 10 micrometers or smaller particles in the air
+ * `o3`: a measure of ground level ozone concentrations in the air
+ * `co`: a measure of carbon monoxide concentrations in the air
+ * `no2`: a measure of nitrogen dioxide concentrations in the air
+ * `so2`: a measure of sulfur dioxide concentrations in the air
+ * `dew`: dew point, the temperature the air needs to be cooled to in order to reach 100% relative humidity
+ * `h`: relative humidity, a measure of moisture in the atmosphere
+ * `p`: atmospheric pressure, a measure of the weight of atoms and molecules that make up the layers in the atmosphere
+ * `t`: temperature, a measure of thermal energy in one or a combined substance at a given time
+ * `w`: wind speed, a measure of air in motion
Sample output:
@@ -97,6 +115,14 @@ This package is a wrapper around an API provided by the World Air Quality Index
1. Ozone is licensed under the GNU GENERAL PUBLIC LICENSE v3.0, and so it cannot be used for closed-source software or for monetary gain.
2. The WAQI API, which Ozone uses to provide data, has it's own [Acceptable Usage Policy](https://aqicn.org/api/tos/). Please refer to it for more details.
+## Contributors
+
+Contributions of any kind are welcome and these are our amazing contributors.
+
+
+
+
+
Enjoy using Ozone!
🥳 🍾 🚀
diff --git a/setup.cfg b/setup.cfg
index 2b867a5..c14ce4b 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = ozon3
-version = 1.4.6
+version = 1.4.7
author = Milind Sharma
author_email = milindsharma8@gmail.com
description = A package to get air quality data using the WAQI API
diff --git a/setup.py b/setup.py
index c73c092..efb2ad0 100644
--- a/setup.py
+++ b/setup.py
@@ -9,8 +9,8 @@
description="A package to get air quality data using the WAQI API",
license="GPLv3+",
url="https://github.com/Milind220/Ozone",
- version="1.4.6",
- download_url="https://github.com/Milind220/Ozone/archive/refs/tags/v1.4.6.tar.gz",
+ version="1.4.7",
+ download_url="https://github.com/Milind220/Ozone/archive/refs/tags/v1.4.7.tar.gz",
packages=setuptools.find_packages(),
install_requires=[
"numpy; python_version>='3'",
diff --git a/src/ozone/ozone.py b/src/ozone/ozone.py
index ad62ca0..b16c634 100644
--- a/src/ozone/ozone.py
+++ b/src/ozone/ozone.py
@@ -8,7 +8,8 @@
Attributes (module level):
CALLS (int=1000): The number of calls per second allowed by the WAQI API is 1000.
- RATE_LIMIT (int=1): The time period in seconds for the max number of calls is 1 second.
+ RATE_LIMIT (int=1): The time period in seconds for the max number of calls is
+ 1 second.
"""
import pandas
@@ -112,12 +113,15 @@ def reset_token(self, token: str) -> None:
self._check_token_validity()
def _format_output(
- self, data_format: str = "df", df: pandas.DataFrame = pandas.DataFrame(),
+ 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'.
+ data_format (str): File format. Defaults to 'df'.
+ Choose from 'csv', 'json', 'xlsx'.
df (pandas.DataFrame,): Dataframe object of air quality data.
Returns:
@@ -133,7 +137,9 @@ def _format_output(
df.to_json("air_quality_data.json")
print("File saved to disk as air_quality_data.json")
elif data_format == "xlsx":
- df.to_excel("air_quality_data.xlsx",)
+ df.to_excel(
+ "air_quality_data.xlsx",
+ )
print("File saved to disk as air_quality_data.xlsx")
else:
raise Exception(
@@ -147,7 +153,8 @@ def _parse_data(
"""Parse the data from the API response
Args:
- data_obj (JSON object returned by json.loads): The data from the API response.
+ data_obj (JSON object returned by json.loads): The data from the API's
+ response.
city (str): The city name.
params (List[str]): The parameters to parse.
@@ -197,19 +204,35 @@ def _AQI_meaning(self, aqi: float) -> Tuple[str, str]:
if 0 <= aqi <= 50:
AQI_meaning = "Good"
- AQI_health_implications = "Air quality is considered satisfactory, and air pollution poses little or no risk"
+ AQI_health_implications = (
+ "Air quality is considered satisfactory, "
+ "and air pollution poses little or no risk"
+ )
elif 51 <= aqi <= 100:
AQI_meaning = "Moderate"
- AQI_health_implications = "Air quality is acceptable; however, for some pollutants there may be a moderate health concern for a very small number of people who are unusually sensitive to air pollution."
+ AQI_health_implications = (
+ "Air quality is acceptable; however, for some pollutants "
+ "there may be a moderate health concern for a very small "
+ "number of people who are unusually sensitive to air pollution."
+ )
elif 101 <= aqi <= 150:
AQI_meaning = "Unhealthy for sensitive group"
- AQI_health_implications = "Members of sensitive groups may experience health effects. The general public is not likely to be affected."
+ AQI_health_implications = (
+ "Members of sensitive groups may experience health effects. "
+ "The general public is not likely to be affected."
+ )
elif 151 <= aqi <= 200:
AQI_meaning = "Unhealthy"
- AQI_health_implications = "Everyone may begin to experience health effects; members of sensitive groups may experience more serious health effects."
+ AQI_health_implications = (
+ "Everyone may begin to experience health effects; members of "
+ "sensitive groups may experience more serious health effects."
+ )
elif 201 <= aqi <= 300:
AQI_meaning = "Very Unhealthy"
- AQI_health_implications = "Health warnings of emergency conditions. The entire population is more likely to be affected."
+ AQI_health_implications = (
+ "Health warnings of emergency conditions. "
+ "The entire population is more likely to be affected."
+ )
elif 301 <= aqi <= 500:
AQI_meaning = "Hazardous"
AQI_health_implications = (
@@ -217,7 +240,8 @@ def _AQI_meaning(self, aqi: float) -> Tuple[str, str]:
)
else:
raise Exception(
- f"{aqi} is not valid air quality index value. Should be between 0 to 500."
+ f"{aqi} is not valid air quality index value. "
+ "Should be between 0 to 500."
)
return AQI_meaning, AQI_health_implications
@@ -269,8 +293,10 @@ 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.
+ 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.
Gets all parameters by default.
@@ -302,8 +328,10 @@ def get_city_air(
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.
+ 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.
Gets all parameters by default.
@@ -326,7 +354,8 @@ def get_city_air(
)
raise Exception(
- f'There is a problem with city "{city}", the returned data: {data_obj}'
+ f'There is a problem with city "{city}", '
+ "the returned data: {data_obj}"
)
row = self._parse_data(data_obj, city, params)
@@ -345,8 +374,10 @@ def get_multiple_coordinate_air(
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.
+ 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.
Gets all parameters by default.
@@ -355,7 +386,8 @@ def get_multiple_coordinate_air(
selected another data format, this dataframe will be empty)
"""
for loc in locations:
- # This just makes sure that it's always a returns a pd.DataFrame. Makes mypy happy.
+ # This just makes sure that it's always a returns a pandas.DataFrame.
+ # Makes mypy happy.
df = pandas.DataFrame(
self.get_coordinate_air(loc[0], loc[1], df=df, params=params)
)
@@ -376,8 +408,10 @@ 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.
+ 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.
Gets all parameters by default.
@@ -403,23 +437,30 @@ def get_multiple_city_air(
Args:
cities (list): A list of cities to get data for.
- data_format (str): File format. Defaults to 'df'. Choose from 'csv', 'json', 'xlsx'.
+ 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.
Gets all parameters by default.
- df (pandas.DataFrame, optional): An existing dataframe to append the data to.
+ 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)
"""
for city in cities:
- # This just makes sure that it's always a returns a pd.DataFrame. Makes mypy happy.
+ # This just makes sure that it's always a returns a pandas.DataFrame.
+ # Makes mypy happy.
df = pandas.DataFrame(self.get_city_air(city=city, df=df, params=params))
df.reset_index(inplace=True, drop=True)
return self._format_output(data_format, df)
- def get_specific_parameter(self, city: str, air_param: str = "",) -> float:
+ def get_specific_parameter(
+ self,
+ city: str,
+ air_param: str = "",
+ ) -> float:
"""Get specific parameter as a float
Args: