env-canada 0.6.0__tar.gz → 0.6.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {env_canada-0.6.0 → env_canada-0.6.2}/PKG-INFO +29 -19
- {env_canada-0.6.0 → env_canada-0.6.2}/README.md +18 -18
- env_canada-0.6.2/env_canada/__init__.py +5 -0
- env_canada-0.6.2/env_canada/constants.py +1 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/ec_radar.py +18 -12
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada.egg-info/PKG-INFO +30 -20
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada.egg-info/SOURCES.txt +6 -1
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada.egg-info/requires.txt +1 -1
- {env_canada-0.6.0 → env_canada-0.6.2}/setup.py +2 -2
- env_canada-0.6.2/tests/test_ec_aqhi.py +34 -0
- env_canada-0.6.2/tests/test_ec_historical.py +30 -0
- env_canada-0.6.2/tests/test_ec_hydro.py +37 -0
- env_canada-0.6.2/tests/test_ec_radar.py +56 -0
- env_canada-0.6.2/tests/test_ec_weather.py +28 -0
- env_canada-0.6.0/env_canada/__init__.py +0 -5
- env_canada-0.6.0/env_canada/constants.py +0 -1
- {env_canada-0.6.0 → env_canada-0.6.2}/LICENSE +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/MANIFEST.in +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/10x20.pbm +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/10x20.pil +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/ec_aqhi.py +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/ec_cache.py +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/ec_exc.py +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/ec_historical.py +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/ec_hydro.py +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada/ec_weather.py +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada.egg-info/dependency_links.txt +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/env_canada.egg-info/top_level.txt +0 -0
- {env_canada-0.6.0 → env_canada-0.6.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: env_canada
|
3
|
-
Version: 0.6.
|
3
|
+
Version: 0.6.2
|
4
4
|
Summary: A package to access meteorological data from Environment Canada
|
5
5
|
Home-page: https://github.com/michaeldavie/env_canada
|
6
6
|
Author: Michael Davie
|
@@ -11,10 +11,21 @@ Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
12
12
|
Description-Content-Type: text/markdown
|
13
13
|
License-File: LICENSE
|
14
|
+
Requires-Dist: aiohttp>=3.9.0
|
15
|
+
Requires-Dist: defusedxml
|
16
|
+
Requires-Dist: geopy
|
17
|
+
Requires-Dist: imageio>=2.28.0
|
18
|
+
Requires-Dist: lxml
|
19
|
+
Requires-Dist: numpy>=1.22.2
|
20
|
+
Requires-Dist: pandas>=1.3.0
|
21
|
+
Requires-Dist: Pillow>=10.0.1
|
22
|
+
Requires-Dist: python-dateutil
|
23
|
+
Requires-Dist: voluptuous
|
14
24
|
|
15
25
|
# Environment Canada (env_canada)
|
26
|
+
|
16
27
|
[](https://badge.fury.io/py/env-canada)
|
17
|
-
[](https://snyk.io/vuln/pip:env-canada@0.6.
|
28
|
+
[](https://snyk.io/vuln/pip:env-canada@0.6.2?utm_source=badge)
|
18
29
|
|
19
30
|
This package provides access to various data sources published by [Environment and Climate Change Canada](https://www.canada.ca/en/environment-climate-change.html).
|
20
31
|
|
@@ -105,7 +116,8 @@ Once updated asynchronously, historical weather data is contained with the `stat
|
|
105
116
|
```python
|
106
117
|
import asyncio
|
107
118
|
|
108
|
-
from env_canada import ECHistorical
|
119
|
+
from env_canada import ECHistorical
|
120
|
+
from env_canada.ec_historical import get_historical_stations
|
109
121
|
|
110
122
|
# search for stations, response contains station_ids
|
111
123
|
coordinates = [53.916944, -122.749444] # [lat, long]
|
@@ -154,7 +166,8 @@ For example :
|
|
154
166
|
```python
|
155
167
|
import pandas as pd
|
156
168
|
import asyncio
|
157
|
-
from env_canada import ECHistoricalRange
|
169
|
+
from env_canada import ECHistoricalRange
|
170
|
+
from env_canada.ec_historical import get_historical_stations
|
158
171
|
from datetime import datetime
|
159
172
|
|
160
173
|
coordinates = ['48.508333', '-68.467667']
|
@@ -167,33 +180,30 @@ ec = ECHistoricalRange(station_id=int(stations.iloc[0,2]), timeframe="daily",
|
|
167
180
|
|
168
181
|
ec.get_data()
|
169
182
|
|
170
|
-
#yield an XML formated str.
|
183
|
+
#yield an XML formated str.
|
171
184
|
# For more options, use ec.to_xml(*arg, **kwargs) with pandas options
|
172
185
|
ec.xml
|
173
|
-
|
186
|
+
|
174
187
|
#yield an CSV formated str.
|
175
188
|
# For more options, use ec.to_csv(*arg, **kwargs) with pandas options
|
176
189
|
ec.csv
|
177
190
|
```
|
178
191
|
|
179
|
-
In this example
|
180
|
-
|
181
|
-
| Date/Time | Longitude (x) | Latitude (y) | Station Name | Climate ID | Year | Month | Day | Data Quality | Max Temp (°C) | Max Temp Flag | Min Temp (°C) | Min Temp Flag | Mean Temp (°C) | Mean Temp Flag | Heat Deg Days (°C) | Heat Deg Days Flag | Cool Deg Days (°C) | Cool Deg Days Flag | Total Rain (mm) | Total Rain Flag | Total Snow (cm) | Total Snow Flag | Total Precip (mm) | Total Precip Flag | Snow on Grnd (cm) | Snow on Grnd Flag | Dir of Max Gust (10s deg) | Dir of Max Gust Flag | Spd of Max Gust (km/h) | Spd of Max Gust Flag | |
|
182
|
-
|--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |
|
183
|
-
| 2022-07-02 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 2 | | 22,8 | | 12,5 | | 17,7 | | 0,3 | | 0 | | | | | | 0 | | | | 26 | | 37 | | |
|
184
|
-
| 2022-07-03 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 3 | | 21,7 | | 10,1 | | 15,9 | | 2,1 | | 0 | | | | | | 0,4 | | | | 28 | | 50 | | |
|
185
|
-
| … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
|
186
|
-
| 2022-07-31 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 31 | | 23,5 | | 14,1 | | 18,8 | | 0 | | 0,8 | | | | | | 0 | | | | 23 | | 31 | | |
|
187
|
-
| 2022-08-01 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 8 | 1 | | 23 | | 15 | | 19 | | 0 | | 1 | | | | | | 0 | | | | 21 | | 35 | | |
|
192
|
+
In this example `ec.df` will be:
|
188
193
|
|
194
|
+
| Date/Time | Longitude (x) | Latitude (y) | Station Name | Climate ID | Year | Month | Day | Data Quality | Max Temp (°C) | Max Temp Flag | Min Temp (°C) | Min Temp Flag | Mean Temp (°C) | Mean Temp Flag | Heat Deg Days (°C) | Heat Deg Days Flag | Cool Deg Days (°C) | Cool Deg Days Flag | Total Rain (mm) | Total Rain Flag | Total Snow (cm) | Total Snow Flag | Total Precip (mm) | Total Precip Flag | Snow on Grnd (cm) | Snow on Grnd Flag | Dir of Max Gust (10s deg) | Dir of Max Gust Flag | Spd of Max Gust (km/h) | Spd of Max Gust Flag | |
|
195
|
+
| ---------- | ------------- | ------------ | --------------------- | ---------- | ---- | ----- | --- | ------------ | -------------- | ------------- | -------------- | ------------- | --------------- | -------------- | ------------------- | ------------------ | ------------------- | ------------------ | --------------- | --------------- | --------------- | --------------- | ----------------- | ----------------- | ----------------- | ----------------- | ------------------------- | -------------------- | ---------------------- | -------------------- | --- |
|
196
|
+
| 2022-07-02 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 2 | | 22,8 | | 12,5 | | 17,7 | | 0,3 | | 0 | | | | | | 0 | | | | 26 | | 37 | | |
|
197
|
+
| 2022-07-03 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 3 | | 21,7 | | 10,1 | | 15,9 | | 2,1 | | 0 | | | | | | 0,4 | | | | 28 | | 50 | | |
|
198
|
+
| … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
|
199
|
+
| 2022-07-31 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 31 | | 23,5 | | 14,1 | | 18,8 | | 0 | | 0,8 | | | | | | 0 | | | | 23 | | 31 | | |
|
200
|
+
| 2022-08-01 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 8 | 1 | | 23 | | 15 | | 19 | | 0 | | 1 | | | | | | 0 | | | | 21 | | 35 | | |
|
189
201
|
|
190
202
|
One should note that july 1st is excluded as the time provided contains specific hours, so it yields only data after or at exactly
|
191
203
|
the time provided.
|
192
204
|
|
193
|
-
To have all the july 1st data in that case, one can provide a datarange without time:
|
194
|
-
of
|
195
|
-
|
196
|
-
|
205
|
+
To have all the july 1st data in that case, one can provide a datarange without time: `datetime(2022, 7, 7)` instead
|
206
|
+
of `datetime(2022, 7, 1, 12, 12)`
|
197
207
|
|
198
208
|
# License
|
199
209
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# Environment Canada (env_canada)
|
2
|
+
|
2
3
|
[](https://badge.fury.io/py/env-canada)
|
3
|
-
[](https://snyk.io/vuln/pip:env-canada@0.6.
|
4
|
+
[](https://snyk.io/vuln/pip:env-canada@0.6.2?utm_source=badge)
|
4
5
|
|
5
6
|
This package provides access to various data sources published by [Environment and Climate Change Canada](https://www.canada.ca/en/environment-climate-change.html).
|
6
7
|
|
@@ -91,7 +92,8 @@ Once updated asynchronously, historical weather data is contained with the `stat
|
|
91
92
|
```python
|
92
93
|
import asyncio
|
93
94
|
|
94
|
-
from env_canada import ECHistorical
|
95
|
+
from env_canada import ECHistorical
|
96
|
+
from env_canada.ec_historical import get_historical_stations
|
95
97
|
|
96
98
|
# search for stations, response contains station_ids
|
97
99
|
coordinates = [53.916944, -122.749444] # [lat, long]
|
@@ -140,7 +142,8 @@ For example :
|
|
140
142
|
```python
|
141
143
|
import pandas as pd
|
142
144
|
import asyncio
|
143
|
-
from env_canada import ECHistoricalRange
|
145
|
+
from env_canada import ECHistoricalRange
|
146
|
+
from env_canada.ec_historical import get_historical_stations
|
144
147
|
from datetime import datetime
|
145
148
|
|
146
149
|
coordinates = ['48.508333', '-68.467667']
|
@@ -153,33 +156,30 @@ ec = ECHistoricalRange(station_id=int(stations.iloc[0,2]), timeframe="daily",
|
|
153
156
|
|
154
157
|
ec.get_data()
|
155
158
|
|
156
|
-
#yield an XML formated str.
|
159
|
+
#yield an XML formated str.
|
157
160
|
# For more options, use ec.to_xml(*arg, **kwargs) with pandas options
|
158
161
|
ec.xml
|
159
|
-
|
162
|
+
|
160
163
|
#yield an CSV formated str.
|
161
164
|
# For more options, use ec.to_csv(*arg, **kwargs) with pandas options
|
162
165
|
ec.csv
|
163
166
|
```
|
164
167
|
|
165
|
-
In this example
|
166
|
-
|
167
|
-
| Date/Time | Longitude (x) | Latitude (y) | Station Name | Climate ID | Year | Month | Day | Data Quality | Max Temp (°C) | Max Temp Flag | Min Temp (°C) | Min Temp Flag | Mean Temp (°C) | Mean Temp Flag | Heat Deg Days (°C) | Heat Deg Days Flag | Cool Deg Days (°C) | Cool Deg Days Flag | Total Rain (mm) | Total Rain Flag | Total Snow (cm) | Total Snow Flag | Total Precip (mm) | Total Precip Flag | Snow on Grnd (cm) | Snow on Grnd Flag | Dir of Max Gust (10s deg) | Dir of Max Gust Flag | Spd of Max Gust (km/h) | Spd of Max Gust Flag | |
|
168
|
-
|--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |
|
169
|
-
| 2022-07-02 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 2 | | 22,8 | | 12,5 | | 17,7 | | 0,3 | | 0 | | | | | | 0 | | | | 26 | | 37 | | |
|
170
|
-
| 2022-07-03 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 3 | | 21,7 | | 10,1 | | 15,9 | | 2,1 | | 0 | | | | | | 0,4 | | | | 28 | | 50 | | |
|
171
|
-
| … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
|
172
|
-
| 2022-07-31 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 31 | | 23,5 | | 14,1 | | 18,8 | | 0 | | 0,8 | | | | | | 0 | | | | 23 | | 31 | | |
|
173
|
-
| 2022-08-01 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 8 | 1 | | 23 | | 15 | | 19 | | 0 | | 1 | | | | | | 0 | | | | 21 | | 35 | | |
|
168
|
+
In this example `ec.df` will be:
|
174
169
|
|
170
|
+
| Date/Time | Longitude (x) | Latitude (y) | Station Name | Climate ID | Year | Month | Day | Data Quality | Max Temp (°C) | Max Temp Flag | Min Temp (°C) | Min Temp Flag | Mean Temp (°C) | Mean Temp Flag | Heat Deg Days (°C) | Heat Deg Days Flag | Cool Deg Days (°C) | Cool Deg Days Flag | Total Rain (mm) | Total Rain Flag | Total Snow (cm) | Total Snow Flag | Total Precip (mm) | Total Precip Flag | Snow on Grnd (cm) | Snow on Grnd Flag | Dir of Max Gust (10s deg) | Dir of Max Gust Flag | Spd of Max Gust (km/h) | Spd of Max Gust Flag | |
|
171
|
+
| ---------- | ------------- | ------------ | --------------------- | ---------- | ---- | ----- | --- | ------------ | -------------- | ------------- | -------------- | ------------- | --------------- | -------------- | ------------------- | ------------------ | ------------------- | ------------------ | --------------- | --------------- | --------------- | --------------- | ----------------- | ----------------- | ----------------- | ----------------- | ------------------------- | -------------------- | ---------------------- | -------------------- | --- |
|
172
|
+
| 2022-07-02 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 2 | | 22,8 | | 12,5 | | 17,7 | | 0,3 | | 0 | | | | | | 0 | | | | 26 | | 37 | | |
|
173
|
+
| 2022-07-03 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 3 | | 21,7 | | 10,1 | | 15,9 | | 2,1 | | 0 | | | | | | 0,4 | | | | 28 | | 50 | | |
|
174
|
+
| … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
|
175
|
+
| 2022-07-31 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 31 | | 23,5 | | 14,1 | | 18,8 | | 0 | | 0,8 | | | | | | 0 | | | | 23 | | 31 | | |
|
176
|
+
| 2022-08-01 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 8 | 1 | | 23 | | 15 | | 19 | | 0 | | 1 | | | | | | 0 | | | | 21 | | 35 | | |
|
175
177
|
|
176
178
|
One should note that july 1st is excluded as the time provided contains specific hours, so it yields only data after or at exactly
|
177
179
|
the time provided.
|
178
180
|
|
179
|
-
To have all the july 1st data in that case, one can provide a datarange without time:
|
180
|
-
of
|
181
|
-
|
182
|
-
|
181
|
+
To have all the july 1st data in that case, one can provide a datarange without time: `datetime(2022, 7, 7)` instead
|
182
|
+
of `datetime(2022, 7, 1, 12, 12)`
|
183
183
|
|
184
184
|
# License
|
185
185
|
|
@@ -0,0 +1 @@
|
|
1
|
+
USER_AGENT = "env_canada/0.6.2"
|
@@ -1,17 +1,18 @@
|
|
1
|
-
from aiohttp.client_exceptions import ClientConnectorError
|
2
1
|
import asyncio
|
3
2
|
import datetime
|
4
|
-
from io import BytesIO
|
5
3
|
import logging
|
6
4
|
import math
|
7
5
|
import os
|
8
|
-
from
|
6
|
+
from io import BytesIO
|
9
7
|
|
10
|
-
from .ec_cache import CacheClientSession as ClientSession
|
11
8
|
import dateutil.parser
|
12
9
|
import defusedxml.ElementTree as et
|
13
10
|
import imageio.v2 as imageio
|
14
11
|
import voluptuous as vol
|
12
|
+
from aiohttp.client_exceptions import ClientConnectorError
|
13
|
+
from PIL import Image, ImageDraw, ImageFont
|
14
|
+
|
15
|
+
from .ec_cache import CacheClientSession as ClientSession
|
15
16
|
|
16
17
|
ATTRIBUTION = {
|
17
18
|
"english": "Data provided by Environment Canada",
|
@@ -331,6 +332,17 @@ class ECRadar(object):
|
|
331
332
|
async def get_loop(self, fps=5):
|
332
333
|
"""Build an animated GIF of recent radar images."""
|
333
334
|
|
335
|
+
def build_image():
|
336
|
+
gif_frames = [imageio.imread(f, mode="RGBA") for f in frames]
|
337
|
+
gif_bytes = imageio.mimwrite(
|
338
|
+
imageio.RETURN_BYTES,
|
339
|
+
gif_frames,
|
340
|
+
format="GIF",
|
341
|
+
duration=duration,
|
342
|
+
subrectangles=True,
|
343
|
+
)
|
344
|
+
return gif_bytes
|
345
|
+
|
334
346
|
"""Build list of frame timestamps."""
|
335
347
|
start, end = await self._get_dimensions()
|
336
348
|
frame_times = [start]
|
@@ -361,12 +373,6 @@ class ECRadar(object):
|
|
361
373
|
"""Assemble animated GIF."""
|
362
374
|
duration = 1000 / fps
|
363
375
|
|
364
|
-
|
365
|
-
gif_bytes =
|
366
|
-
imageio.RETURN_BYTES,
|
367
|
-
gif_frames,
|
368
|
-
format="GIF",
|
369
|
-
duration=duration,
|
370
|
-
subrectangles=True,
|
371
|
-
)
|
376
|
+
loop = asyncio.get_running_loop()
|
377
|
+
gif_bytes = await loop.run_in_executor(None, build_image)
|
372
378
|
return gif_bytes
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
|
-
Name:
|
3
|
-
Version: 0.6.
|
2
|
+
Name: env_canada
|
3
|
+
Version: 0.6.2
|
4
4
|
Summary: A package to access meteorological data from Environment Canada
|
5
5
|
Home-page: https://github.com/michaeldavie/env_canada
|
6
6
|
Author: Michael Davie
|
@@ -11,10 +11,21 @@ Classifier: License :: OSI Approved :: MIT License
|
|
11
11
|
Classifier: Operating System :: OS Independent
|
12
12
|
Description-Content-Type: text/markdown
|
13
13
|
License-File: LICENSE
|
14
|
+
Requires-Dist: aiohttp>=3.9.0
|
15
|
+
Requires-Dist: defusedxml
|
16
|
+
Requires-Dist: geopy
|
17
|
+
Requires-Dist: imageio>=2.28.0
|
18
|
+
Requires-Dist: lxml
|
19
|
+
Requires-Dist: numpy>=1.22.2
|
20
|
+
Requires-Dist: pandas>=1.3.0
|
21
|
+
Requires-Dist: Pillow>=10.0.1
|
22
|
+
Requires-Dist: python-dateutil
|
23
|
+
Requires-Dist: voluptuous
|
14
24
|
|
15
25
|
# Environment Canada (env_canada)
|
26
|
+
|
16
27
|
[](https://badge.fury.io/py/env-canada)
|
17
|
-
[](https://snyk.io/vuln/pip:env-canada@0.6.
|
28
|
+
[](https://snyk.io/vuln/pip:env-canada@0.6.2?utm_source=badge)
|
18
29
|
|
19
30
|
This package provides access to various data sources published by [Environment and Climate Change Canada](https://www.canada.ca/en/environment-climate-change.html).
|
20
31
|
|
@@ -105,7 +116,8 @@ Once updated asynchronously, historical weather data is contained with the `stat
|
|
105
116
|
```python
|
106
117
|
import asyncio
|
107
118
|
|
108
|
-
from env_canada import ECHistorical
|
119
|
+
from env_canada import ECHistorical
|
120
|
+
from env_canada.ec_historical import get_historical_stations
|
109
121
|
|
110
122
|
# search for stations, response contains station_ids
|
111
123
|
coordinates = [53.916944, -122.749444] # [lat, long]
|
@@ -154,7 +166,8 @@ For example :
|
|
154
166
|
```python
|
155
167
|
import pandas as pd
|
156
168
|
import asyncio
|
157
|
-
from env_canada import ECHistoricalRange
|
169
|
+
from env_canada import ECHistoricalRange
|
170
|
+
from env_canada.ec_historical import get_historical_stations
|
158
171
|
from datetime import datetime
|
159
172
|
|
160
173
|
coordinates = ['48.508333', '-68.467667']
|
@@ -167,33 +180,30 @@ ec = ECHistoricalRange(station_id=int(stations.iloc[0,2]), timeframe="daily",
|
|
167
180
|
|
168
181
|
ec.get_data()
|
169
182
|
|
170
|
-
#yield an XML formated str.
|
183
|
+
#yield an XML formated str.
|
171
184
|
# For more options, use ec.to_xml(*arg, **kwargs) with pandas options
|
172
185
|
ec.xml
|
173
|
-
|
186
|
+
|
174
187
|
#yield an CSV formated str.
|
175
188
|
# For more options, use ec.to_csv(*arg, **kwargs) with pandas options
|
176
189
|
ec.csv
|
177
190
|
```
|
178
191
|
|
179
|
-
In this example
|
180
|
-
|
181
|
-
| Date/Time | Longitude (x) | Latitude (y) | Station Name | Climate ID | Year | Month | Day | Data Quality | Max Temp (°C) | Max Temp Flag | Min Temp (°C) | Min Temp Flag | Mean Temp (°C) | Mean Temp Flag | Heat Deg Days (°C) | Heat Deg Days Flag | Cool Deg Days (°C) | Cool Deg Days Flag | Total Rain (mm) | Total Rain Flag | Total Snow (cm) | Total Snow Flag | Total Precip (mm) | Total Precip Flag | Snow on Grnd (cm) | Snow on Grnd Flag | Dir of Max Gust (10s deg) | Dir of Max Gust Flag | Spd of Max Gust (km/h) | Spd of Max Gust Flag | |
|
182
|
-
|--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |--- |
|
183
|
-
| 2022-07-02 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 2 | | 22,8 | | 12,5 | | 17,7 | | 0,3 | | 0 | | | | | | 0 | | | | 26 | | 37 | | |
|
184
|
-
| 2022-07-03 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 3 | | 21,7 | | 10,1 | | 15,9 | | 2,1 | | 0 | | | | | | 0,4 | | | | 28 | | 50 | | |
|
185
|
-
| … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
|
186
|
-
| 2022-07-31 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 31 | | 23,5 | | 14,1 | | 18,8 | | 0 | | 0,8 | | | | | | 0 | | | | 23 | | 31 | | |
|
187
|
-
| 2022-08-01 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 8 | 1 | | 23 | | 15 | | 19 | | 0 | | 1 | | | | | | 0 | | | | 21 | | 35 | | |
|
192
|
+
In this example `ec.df` will be:
|
188
193
|
|
194
|
+
| Date/Time | Longitude (x) | Latitude (y) | Station Name | Climate ID | Year | Month | Day | Data Quality | Max Temp (°C) | Max Temp Flag | Min Temp (°C) | Min Temp Flag | Mean Temp (°C) | Mean Temp Flag | Heat Deg Days (°C) | Heat Deg Days Flag | Cool Deg Days (°C) | Cool Deg Days Flag | Total Rain (mm) | Total Rain Flag | Total Snow (cm) | Total Snow Flag | Total Precip (mm) | Total Precip Flag | Snow on Grnd (cm) | Snow on Grnd Flag | Dir of Max Gust (10s deg) | Dir of Max Gust Flag | Spd of Max Gust (km/h) | Spd of Max Gust Flag | |
|
195
|
+
| ---------- | ------------- | ------------ | --------------------- | ---------- | ---- | ----- | --- | ------------ | -------------- | ------------- | -------------- | ------------- | --------------- | -------------- | ------------------- | ------------------ | ------------------- | ------------------ | --------------- | --------------- | --------------- | --------------- | ----------------- | ----------------- | ----------------- | ----------------- | ------------------------- | -------------------- | ---------------------- | -------------------- | --- |
|
196
|
+
| 2022-07-02 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 2 | | 22,8 | | 12,5 | | 17,7 | | 0,3 | | 0 | | | | | | 0 | | | | 26 | | 37 | | |
|
197
|
+
| 2022-07-03 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 3 | | 21,7 | | 10,1 | | 15,9 | | 2,1 | | 0 | | | | | | 0,4 | | | | 28 | | 50 | | |
|
198
|
+
| … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … | … |
|
199
|
+
| 2022-07-31 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 7 | 31 | | 23,5 | | 14,1 | | 18,8 | | 0 | | 0,8 | | | | | | 0 | | | | 23 | | 31 | | |
|
200
|
+
| 2022-08-01 | -68,47 | 48,51 | POINTE-AU-PERE (INRS) | 7056068 | 2022 | 8 | 1 | | 23 | | 15 | | 19 | | 0 | | 1 | | | | | | 0 | | | | 21 | | 35 | | |
|
189
201
|
|
190
202
|
One should note that july 1st is excluded as the time provided contains specific hours, so it yields only data after or at exactly
|
191
203
|
the time provided.
|
192
204
|
|
193
|
-
To have all the july 1st data in that case, one can provide a datarange without time:
|
194
|
-
of
|
195
|
-
|
196
|
-
|
205
|
+
To have all the july 1st data in that case, one can provide a datarange without time: `datetime(2022, 7, 7)` instead
|
206
|
+
of `datetime(2022, 7, 1, 12, 12)`
|
197
207
|
|
198
208
|
# License
|
199
209
|
|
@@ -17,4 +17,9 @@ env_canada.egg-info/PKG-INFO
|
|
17
17
|
env_canada.egg-info/SOURCES.txt
|
18
18
|
env_canada.egg-info/dependency_links.txt
|
19
19
|
env_canada.egg-info/requires.txt
|
20
|
-
env_canada.egg-info/top_level.txt
|
20
|
+
env_canada.egg-info/top_level.txt
|
21
|
+
tests/test_ec_aqhi.py
|
22
|
+
tests/test_ec_historical.py
|
23
|
+
tests/test_ec_hydro.py
|
24
|
+
tests/test_ec_radar.py
|
25
|
+
tests/test_ec_weather.py
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
5
5
|
|
6
6
|
setuptools.setup(
|
7
7
|
name="env_canada",
|
8
|
-
version="0.6.
|
8
|
+
version="0.6.2",
|
9
9
|
author="Michael Davie",
|
10
10
|
author_email="michael.davie@gmail.com",
|
11
11
|
description="A package to access meteorological data from Environment Canada",
|
@@ -16,7 +16,7 @@ setuptools.setup(
|
|
16
16
|
packages=setuptools.find_packages(exclude=["tests", "tests.*"]),
|
17
17
|
include_package_data=True,
|
18
18
|
install_requires=[
|
19
|
-
"aiohttp",
|
19
|
+
"aiohttp>=3.9.0",
|
20
20
|
"defusedxml",
|
21
21
|
"geopy",
|
22
22
|
"imageio>=2.28.0",
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import asyncio
|
2
|
+
from datetime import datetime
|
3
|
+
|
4
|
+
import pytest
|
5
|
+
|
6
|
+
from env_canada import ec_aqhi, ECAirQuality
|
7
|
+
|
8
|
+
|
9
|
+
def test_get_aqhi_regions():
|
10
|
+
regions = asyncio.run(ec_aqhi.get_aqhi_regions("EN"))
|
11
|
+
assert len(regions) > 0
|
12
|
+
|
13
|
+
|
14
|
+
@pytest.mark.parametrize(
|
15
|
+
"init_parameters",
|
16
|
+
[{"coordinates": (50, -100)}, {"zone_id": "ont", "region_id": "FEVNT"}],
|
17
|
+
)
|
18
|
+
def test_ecaqhi(init_parameters):
|
19
|
+
aqhi = ECAirQuality(**init_parameters)
|
20
|
+
assert isinstance(aqhi, ECAirQuality)
|
21
|
+
|
22
|
+
|
23
|
+
@pytest.fixture()
|
24
|
+
def test_aqhi():
|
25
|
+
return ECAirQuality(coordinates=(49.91, -97.24))
|
26
|
+
|
27
|
+
|
28
|
+
def test_update(test_aqhi):
|
29
|
+
asyncio.run(test_aqhi.update())
|
30
|
+
assert isinstance(test_aqhi.current, float) or test_aqhi.current is None
|
31
|
+
assert all([isinstance(p, str) for p in test_aqhi.forecasts["daily"].keys()])
|
32
|
+
assert all([isinstance(f, int) for f in test_aqhi.forecasts["daily"].values()])
|
33
|
+
assert all([isinstance(d, datetime) for d in test_aqhi.forecasts["hourly"].keys()])
|
34
|
+
assert all([isinstance(f, int) for f in test_aqhi.forecasts["hourly"].values()])
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import asyncio
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from env_canada import ECHistorical
|
6
|
+
|
7
|
+
|
8
|
+
@pytest.mark.parametrize(
|
9
|
+
"init_parameters", [
|
10
|
+
{"station_id": 48370, "year": 2021},
|
11
|
+
{"station_id": 48370, "year": 2021, "language": "english"},
|
12
|
+
{"station_id": 48370, "year": 2021, "language": "french"},
|
13
|
+
{"station_id": 48370, "year": 2021, "format": "csv"},
|
14
|
+
{"station_id": 48370, "year": 2021, "format": "xml"},
|
15
|
+
{"station_id": 48370, "year": 2021, "month": 5, "format": "xml", "timeframe": 1},
|
16
|
+
{"station_id": 48370, "year": 2021, "format": "csv", "timeframe": 1},
|
17
|
+
]
|
18
|
+
)
|
19
|
+
def test_echistorical(init_parameters):
|
20
|
+
weather = ECHistorical(**init_parameters)
|
21
|
+
assert isinstance(weather, ECHistorical)
|
22
|
+
|
23
|
+
@pytest.fixture()
|
24
|
+
def test_historical():
|
25
|
+
return ECHistorical(station_id=48370, year=2021)
|
26
|
+
|
27
|
+
def test_update(test_historical):
|
28
|
+
asyncio.run(test_historical.update())
|
29
|
+
assert test_historical.metadata
|
30
|
+
assert test_historical.station_data
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import asyncio
|
2
|
+
from datetime import datetime
|
3
|
+
|
4
|
+
import pytest
|
5
|
+
|
6
|
+
from env_canada import ec_hydro, ECHydro
|
7
|
+
|
8
|
+
|
9
|
+
def test_get_hydro_sites():
|
10
|
+
sites = asyncio.run(ec_hydro.get_hydro_sites())
|
11
|
+
assert len(sites) > 0
|
12
|
+
|
13
|
+
|
14
|
+
@pytest.mark.parametrize(
|
15
|
+
"init_parameters",
|
16
|
+
[{"coordinates": (50, -100)}, {"province": "ON", "station": "02KF005"}],
|
17
|
+
)
|
18
|
+
def test_echydro(init_parameters):
|
19
|
+
hydro = ECHydro(**init_parameters)
|
20
|
+
assert isinstance(hydro, ECHydro)
|
21
|
+
asyncio.run(hydro.update())
|
22
|
+
assert isinstance(hydro.timestamp, datetime)
|
23
|
+
assert isinstance(hydro.measurements["water_level"]["value"], float)
|
24
|
+
if hydro.measurements.get("discharge"):
|
25
|
+
assert isinstance(hydro.measurements["discharge"]["value"], float)
|
26
|
+
|
27
|
+
|
28
|
+
@pytest.fixture()
|
29
|
+
def test_hydro():
|
30
|
+
return ECHydro(province="ON", station="02KF005")
|
31
|
+
|
32
|
+
|
33
|
+
def test_update(test_hydro):
|
34
|
+
asyncio.run(test_hydro.update())
|
35
|
+
assert isinstance(test_hydro.timestamp, datetime)
|
36
|
+
assert isinstance(test_hydro.measurements["water_level"]["value"], float)
|
37
|
+
assert isinstance(test_hydro.measurements["discharge"]["value"], float)
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import asyncio
|
2
|
+
from datetime import datetime, date
|
3
|
+
from io import BytesIO
|
4
|
+
from PIL import Image
|
5
|
+
|
6
|
+
import pytest
|
7
|
+
|
8
|
+
from env_canada import ECRadar
|
9
|
+
|
10
|
+
|
11
|
+
@pytest.mark.parametrize(
|
12
|
+
"init_parameters",
|
13
|
+
[
|
14
|
+
{"coordinates": (50, -100), "precip_type": "snow", "legend": False},
|
15
|
+
{"coordinates": (50, -100), "precip_type": "rain", "timestamp": False},
|
16
|
+
{"coordinates": (50, -100)},
|
17
|
+
{"coordinates": (50, -100), "precip_type": None},
|
18
|
+
],
|
19
|
+
)
|
20
|
+
def test_ecradar(init_parameters):
|
21
|
+
radar = ECRadar(**init_parameters)
|
22
|
+
frame = asyncio.run(radar.get_latest_frame())
|
23
|
+
image = Image.open(BytesIO(frame))
|
24
|
+
assert image.format == "PNG"
|
25
|
+
|
26
|
+
|
27
|
+
@pytest.fixture
|
28
|
+
def test_radar():
|
29
|
+
return ECRadar(coordinates=(50, -100))
|
30
|
+
|
31
|
+
|
32
|
+
def test_get_dimensions(test_radar):
|
33
|
+
dimensions = asyncio.run(test_radar._get_dimensions())
|
34
|
+
assert isinstance(dimensions[0], datetime) and isinstance(dimensions[1], datetime)
|
35
|
+
|
36
|
+
|
37
|
+
def test_get_latest_frame(test_radar):
|
38
|
+
frame = asyncio.run(test_radar.get_latest_frame())
|
39
|
+
image = Image.open(BytesIO(frame))
|
40
|
+
assert image.format == "PNG"
|
41
|
+
|
42
|
+
|
43
|
+
def test_get_loop(test_radar):
|
44
|
+
loop = asyncio.run(test_radar.get_loop())
|
45
|
+
image = Image.open(BytesIO(loop))
|
46
|
+
assert image.format == "GIF" and image.is_animated
|
47
|
+
|
48
|
+
|
49
|
+
def test_set_precip_type(test_radar):
|
50
|
+
test_radar.precip_type = "auto"
|
51
|
+
assert test_radar.precip_type == "auto"
|
52
|
+
|
53
|
+
if date.today().month in range(4, 11):
|
54
|
+
assert test_radar.layer_key == "rain"
|
55
|
+
else:
|
56
|
+
assert test_radar.layer_key == "snow"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import asyncio
|
2
|
+
|
3
|
+
import pytest
|
4
|
+
|
5
|
+
from env_canada import ec_weather, ECWeather
|
6
|
+
|
7
|
+
|
8
|
+
def test_get_ec_sites():
|
9
|
+
sites = asyncio.run(ec_weather.get_ec_sites())
|
10
|
+
assert len(sites) > 0
|
11
|
+
|
12
|
+
|
13
|
+
@pytest.mark.parametrize(
|
14
|
+
"init_parameters", [{"coordinates": (50, -100)}, {"station_id": "ON/s0000430"}]
|
15
|
+
)
|
16
|
+
def test_ecweather(init_parameters):
|
17
|
+
weather = ECWeather(**init_parameters)
|
18
|
+
assert isinstance(weather, ECWeather)
|
19
|
+
|
20
|
+
|
21
|
+
@pytest.fixture()
|
22
|
+
def with_conditions():
|
23
|
+
return ECWeather(station_id="ON/s0000430")
|
24
|
+
|
25
|
+
|
26
|
+
def test_update_with_conditions(with_conditions):
|
27
|
+
asyncio.run(with_conditions.update())
|
28
|
+
assert with_conditions.conditions
|
@@ -1 +0,0 @@
|
|
1
|
-
USER_AGENT = "env_canada/0.6.0"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|