Skip to content

Commit 658fa6d

Browse files
Merge pull request #1 from sakethramanujam/v0.3-dev
v0.3
2 parents c9ff082 + 3b82e1a commit 658fa6d

7 files changed

Lines changed: 182 additions & 50 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: Client Tests
2+
3+
on: [pull_request]
4+
5+
jobs:
6+
test:
7+
runs-on: ubuntu-18.04
8+
steps:
9+
- uses: actions/checkout@v1
10+
- name: Set up Python 3.7
11+
uses: actions/setup-python@v1
12+
with:
13+
python-version: 3.7
14+
- name: Install dependencies and test
15+
env:
16+
working-directory: cpcbccr-python-client
17+
run: |
18+
python -m pip install --upgrade pip
19+
python setup.py install
20+
pip install pytest
21+
pytest tests/*

‎README.md‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,19 @@ $ pip install cpcbccr
4040
criteria='24 Hours')
4141
4242
```
43-
> For more supported criteria check `doc-strings`
43+
> For more supported criteria check `doc-string.`
44+
45+
- Save Data
46+
47+
```
48+
>>> cpcb.save_data(path='/path/to/file.csv',
49+
from_date='01-01-2020',
50+
end_date = '02-01-2020',
51+
station_id = 'site_279',
52+
criteria = '24 Hours')
53+
```
54+
> Supported Fileformats: `csv`, `xlsx`, `json`
55+
4456

4557
## License
4658

‎cpcbccr/cpcbccr.py‎

Lines changed: 77 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
import requests
44
import pandas as pd
55

6-
76
API_URL = "https://love-the-air.herokuapp.com/api"
8-
pd.DataFrame()
97

108

119
def get_states() -> List[str]:
@@ -18,14 +16,11 @@ def get_states() -> List[str]:
1816
>>> states
1917
['Andhra Pradesh','Karnataka', 'Assam',....]
2018
"""
21-
try:
22-
r = requests.get(f'{API_URL}/states')
23-
status = r.status_code
24-
if status != 200:
25-
Exception(f'failed to fetch states {r.status_code}')
26-
return r.json()['states']
27-
except Exception as e:
28-
print(e)
19+
r = requests.get(f'{API_URL}/states')
20+
status = r.status_code
21+
if status != 200:
22+
raise Exception(f'failed to fetch states {r.status_code}')
23+
return r.json()['states']
2924

3025

3126
def get_cities(state: str) -> List[str]:
@@ -46,14 +41,11 @@ def get_cities(state: str) -> List[str]:
4641
>>> cities
4742
['Eloor', 'Ernakulam', 'Kannur', 'Kochi', 'Kollam', 'Kozhikode', 'Thiruvananthapuram']
4843
"""
49-
try:
50-
r = requests.get(f'{API_URL}/state/{state}')
51-
status = r.status_code
52-
if status != 200:
53-
Exception(f'failed to fetch cities with status:{status}')
54-
return r.json()['cities']
55-
except Exception as e:
56-
print(e)
44+
r = requests.get(f'{API_URL}/state/{state}')
45+
status = r.status_code
46+
if status != 200:
47+
raise Exception(f'failed to fetch cities with status:{status}')
48+
return r.json()['cities']
5749

5850

5951
def get_stations(city: str) -> List[dict]:
@@ -73,14 +65,11 @@ def get_stations(city: str) -> List[dict]:
7365
>>> stations
7466
[{'id': 'site_5334', 'live': True, 'name': 'Polayathode, Kollam - Kerala PCB'}]
7567
"""
76-
try:
77-
r = requests.get(f'{API_URL}/city/{city}')
78-
status = r.status_code
79-
if status != 200:
80-
Exception(f'failed to fetch stations with status:{status}')
81-
return r.json()['stations']
82-
except Exception as e:
83-
print(e)
68+
r = requests.get(f'{API_URL}/city/{city}')
69+
status = r.status_code
70+
if status != 200:
71+
raise Exception(f'failed to fetch stations with status:{status}')
72+
return r.json()['stations']
8473

8574

8675
def get_data(from_date: str, to_date: str,
@@ -123,31 +112,71 @@ def get_data(from_date: str, to_date: str,
123112
"station_id": station_id,
124113
"criteria": criteria
125114
}
126-
try:
127-
r = requests.post(f'{API_URL}/data', json=payload)
128-
status = r.status_code
129-
if status == 422:
130-
print(r.json())
131-
elif status == 200:
132-
return _format(json=r.json())
133-
except Exception as e:
134-
print(e)
135-
136-
137-
def _format(json: dict) -> pd.DataFrame:
115+
r = requests.post(f'{API_URL}/data', json=payload)
116+
status = r.status_code
117+
if status == 422:
118+
print(r.json())
119+
elif status == 200:
120+
return _format(json_data=r.json())
121+
122+
123+
def _format(json_data: dict) -> pd.DataFrame:
138124
"""
139125
Return a well formatted Dataframe from json
140126
141127
Parameters
142128
----------
143-
json: json response from request response
129+
json_data: json response from request response
130+
"""
131+
data = json_data['data']
132+
if not data:
133+
raise Exception("API returned empty data")
134+
else:
135+
df = pd.DataFrame(data=data).drop('exceeding', axis=1)
136+
columns = []
137+
for _, col in enumerate(df.columns):
138+
if '_' in col:
139+
col = col.split('_')[-1]
140+
columns.append(col)
141+
df.columns = columns
142+
return df
143+
144+
def save_data(path: str, from_date: str, to_date: str,
145+
station_id: str, criteria: str):
146+
"""
147+
wrapper around get data method to save
148+
data into a file
149+
150+
Parameters
151+
----------
152+
path : path to store file
153+
from_date : str/ISO datetime
154+
Starting Date from which data is required
155+
to_date : str/ISO datetime
156+
End Date until which the date is required
157+
station_id : str
158+
Station Id as listed in the station dictionary
159+
criteria: str
160+
Frequency of data required
161+
Supported Criteria
162+
- 24 Hours
163+
- 8 Hours
164+
- 4 Hours
165+
- 1 Hours
166+
- 30 Minute
167+
- 15 Minute
144168
"""
145-
data = json['data']
146-
df = pd.DataFrame(data=data).drop('exceeding', axis=1)
147-
columns = []
148-
for _, col in enumerate(df.columns):
149-
if '_' in col:
150-
col = col.split('_')[-1]
151-
columns.append(col)
152-
df.columns = columns
153-
return df
169+
formats = ['csv', 'xlsx', 'json']
170+
ff = path.split('.')[-1]
171+
df = get_data(from_date=from_date,
172+
to_date=to_date,
173+
station_id=station_id,
174+
criteria=criteria)
175+
if ff not in formats:
176+
raise Exception(f'FileFormat {ff} Not Supported!')
177+
if ff == 'csv':
178+
df.to_csv(path, index=False)
179+
elif ff == 'excel':
180+
df.to_excel(path, index=False)
181+
elif ff == 'json':
182+
df.to_json(path, index=False)

‎setup.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
description="An unofficial python client to obtain cpcb ccr data",
1414
long_description=readme,
1515
long_description_content_type='text/markdown',
16-
version="0.2",
16+
version="0.3",
1717
python_requires='>=3.6',
1818
install_requires=['requests', 'pandas'],
1919
author='Saketha Ramanujam',

‎tests/__init__.py‎

Whitespace-only changes.

‎tests/test_data_methods.py‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import cpcbccr as cpcb
2+
import pandas as pd
3+
import pytest
4+
5+
expected_data = {'from date': {0: '01-Jan-2020 - 00:00'},
6+
'AT': {0: '15.57'},
7+
'BP': {0: '732.58'},
8+
'Benzene': {0: '8.03'},
9+
'NO': {0: '21.52'},
10+
'NO2': {0: '59.95'},
11+
'NOx': {0: '30.89'},
12+
'Ozone': {0: '28.57'},
13+
'PM2.5': {0: '274.89'},
14+
'RH': {0: '76.24'},
15+
'SO2': {0: '17.72'},
16+
'SR': {0: '58.18'},
17+
'Toluene': {0: '15.94'},
18+
'VWS': {0: '-1.33'},
19+
'WD': {0: '188.71'},
20+
'WS': {0: '0.76'},
21+
'Xylene': {0: '9.93'},
22+
'to date': {0: '02-Jan-2020 - 00:00'}}
23+
24+
25+
def test_get_data_success():
26+
data = cpcb.get_data(from_date='01-01-2020', to_date='01-01-2020',
27+
criteria='24 Hours', station_id='site_273')
28+
assert data.to_dict() == expected_data
29+
30+
31+
def test_get_data_failure():
32+
with pytest.raises(Exception):
33+
cpcb.get_data(from_date='01-01-2020',
34+
criteria='24 Hours', station_id='site_273')
35+
36+
with pytest.raises(Exception):
37+
cpcb.get_data(to_date='01-01-2020',
38+
criteria='24 Hours', station_id='site_273')
39+
with pytest.raises(Exception):
40+
cpcb.get_data(from_date='01-01-2020', to_date='01-01-2020',
41+
criteria='24 Hours')

‎tests/test_get_methods.py‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import cpcbccr as cpcb
2+
import pytest
3+
4+
5+
def test_get_states():
6+
states = cpcb.get_states()
7+
assert len(states) > 0
8+
9+
10+
def test_get_cities_success():
11+
cities = cpcb.get_cities('Assam')
12+
assert cities == ['Guwahati']
13+
14+
15+
def test_get_cities_failure():
16+
with pytest.raises(Exception):
17+
cpcb.get_cities('qwerty')
18+
19+
20+
def test_get_stations_success():
21+
stations = cpcb.get_stations('Guwahati')
22+
assert stations == [{'id': 'site_5073',
23+
'live': True,
24+
'name': 'Railway Colony, Guwahati - APCB'}]
25+
26+
27+
def test_get_stations_failure():
28+
with pytest.raises(Exception):
29+
cpcb.get_stations('qwerty')

0 commit comments

Comments
 (0)