├── .gitignore ├── darksky ├── __init__.py ├── data.py └── forecast.py ├── LICENSE ├── setup.py ├── test ├── __init__.py └── response.json └── README.rst /.gitignore: -------------------------------------------------------------------------------- 1 | *.egg-info 2 | *.pyc 3 | dist 4 | build 5 | __pycache__ 6 | -------------------------------------------------------------------------------- /darksky/__init__.py: -------------------------------------------------------------------------------- 1 | # __init__.py 2 | 3 | from .forecast import Forecast 4 | 5 | 6 | def forecast(key, latitude, longitude, time=None, timeout=None, **queries): 7 | return Forecast(key, latitude, longitude, time, timeout, **queries) 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Lukas Kubis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup 3 | 4 | # use pandoc to convert 5 | with open(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'README.rst')) as f: 6 | README = f.read() 7 | 8 | setup(name='darkskylib', 9 | version='0.3.91', 10 | description='The Dark Sky API wrapper', 11 | long_description=README, 12 | url='https://github.com/lukaskubis/darkskylib', 13 | author='Lukas Kubis', 14 | author_email='contact@lukaskubis.com', 15 | license='MIT', 16 | classifiers=[ 17 | 'Development Status :: 4 - Beta', 18 | 'License :: OSI Approved :: MIT License', 19 | 'Topic :: Scientific/Engineering :: Atmospheric Science', 20 | 'Topic :: Home Automation', 21 | 'Programming Language :: Python :: 2', 22 | 'Programming Language :: Python :: 2.6', 23 | 'Programming Language :: Python :: 2.7', 24 | 'Programming Language :: Python :: 3', 25 | 'Programming Language :: Python :: 3.3', 26 | 'Programming Language :: Python :: 3.4', 27 | 'Programming Language :: Python :: 3.5', 28 | 'Programming Language :: Python :: 3.6', 29 | 'Programming Language :: Python :: 3.7', 30 | 'Operating System :: OS Independent', 31 | ], 32 | keywords='darksky dark-sky dark sky forecast home weather home-weather weather-station', 33 | packages=['darksky'], 34 | install_requires=[ 35 | 'future', 36 | 'requests', 37 | ], 38 | test_suite='test', 39 | zip_safe=True 40 | ) 41 | -------------------------------------------------------------------------------- /darksky/data.py: -------------------------------------------------------------------------------- 1 | # data.py 2 | 3 | 4 | class DataPoint(object): 5 | def __init__(self, data): 6 | self._data = data 7 | 8 | if isinstance(self._data, dict): 9 | for name, val in self._data.items(): 10 | setattr(self, name, val) 11 | 12 | if isinstance(self._data, list): 13 | setattr(self, 'data', self._data) 14 | 15 | def __setattr__(self, name, val): 16 | def setval(new_val=None): 17 | return object.__setattr__(self, name, new_val if new_val else val) 18 | 19 | # regular value 20 | if not isinstance(val, (list, dict)) or name == '_data': 21 | return setval() 22 | 23 | # set specific data handlers 24 | if name in ('alerts', 'flags'): 25 | return setval(eval(name.capitalize())(val)) 26 | 27 | # data 28 | if isinstance(val, list): 29 | val = [DataPoint(v) if isinstance(v, dict) else v for v in val] 30 | return setval(val) 31 | 32 | # set general data handlers 33 | setval(DataBlock(val) if 'data' in val.keys() else DataPoint(val)) 34 | 35 | def __getitem__(self, key): 36 | return self._data[key] 37 | 38 | def __len__(self): 39 | return len(self._data) 40 | 41 | 42 | class DataBlock(DataPoint): 43 | def __iter__(self): 44 | return self.data.__iter__() 45 | 46 | def __getitem__(self, index): 47 | # keys in darksky API datablocks are always str 48 | if isinstance(index, str): 49 | return self._data[index] 50 | return self.data.__getitem__(index) 51 | 52 | def __len__(self): 53 | return self.data.__len__() 54 | 55 | 56 | class Flags(DataPoint): 57 | def __setattr__(self, name, value): 58 | return object.__setattr__(self, name.replace('-', '_'), value) 59 | 60 | 61 | class Alerts(DataBlock): 62 | pass 63 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pickle 3 | import unittest 4 | 5 | import darksky 6 | import requests 7 | 8 | 9 | class TestPickle(unittest.TestCase): 10 | """ Forecast pickling """ 11 | @classmethod 12 | def setUpClass(cls): 13 | def mock_request_get(*args, **kwargs): 14 | response = type('Response', (object,), {}) 15 | response.headers = {} 16 | response.status_code = 200 17 | 18 | with open('./test/response.json', 'r') as fixture: 19 | response.text = fixture.read() 20 | 21 | return response 22 | 23 | cls.request_get = requests.get 24 | requests.get = mock_request_get 25 | 26 | @classmethod 27 | def tearDownClass(cls): 28 | os.system('find . -name "*.pickle" -exec rm {} \;') 29 | requests.get = cls.request_get 30 | 31 | def test_pickle(self): 32 | location = -77.843906, 166.686520 # McMurdo station, antarctica 33 | 34 | # This doesn't actually hit the API since we mocked out the request lib 35 | forecast = darksky.forecast('test_key', *location) 36 | 37 | # Make sure we got the right data, via our mock 38 | self.assertEqual(forecast.currently.temperature, -23.58) 39 | 40 | # Ensure pickling by actually pickling 41 | with open('./forecast.pickle', 'wb') as outfile: 42 | pickle.dump(forecast, outfile) 43 | 44 | # Check that the file exists 45 | self.assertTrue(os.path.exists('./forecast.pickle')) 46 | 47 | def test_unpickle(self): 48 | # Check that the previous test, which writes out the pickle, succeeded 49 | self.assertTrue(os.path.exists('./forecast.pickle')) 50 | 51 | # Load the pickle file 52 | with open('./forecast.pickle', 'rb') as infile: 53 | forecast = pickle.load(infile) 54 | 55 | # Make sure it loaded right 56 | self.assertTrue(forecast) 57 | self.assertEqual(forecast.currently.temperature, -23.58) 58 | 59 | 60 | if __name__ == '__main__': 61 | unittest.main() 62 | -------------------------------------------------------------------------------- /darksky/forecast.py: -------------------------------------------------------------------------------- 1 | # forecast.py 2 | from __future__ import print_function 3 | from builtins import super 4 | 5 | import json 6 | import sys 7 | import requests 8 | 9 | from .data import DataPoint 10 | 11 | _API_URL = 'https://api.darksky.net/forecast' 12 | 13 | 14 | class Forecast(DataPoint): 15 | def __init__(self, key, latitude, longitude, time=None, timeout=None, **queries): 16 | self._parameters = dict(key=key, latitude=latitude, longitude=longitude, time=time) 17 | self.refresh(timeout, **queries) 18 | 19 | def __setattr__(self, key, value): 20 | if key in ('_queries', '_parameters', '_data'): 21 | return object.__setattr__(self, key, value) 22 | return super().__setattr__(key, value) 23 | 24 | def __getattr__(self, key): 25 | currently = object.__getattribute__(self, 'currently') 26 | _data = object.__getattribute__(currently, '_data') 27 | if key in _data.keys(): 28 | return _data[key] 29 | return object.__getattribute__(self, key) 30 | 31 | def __enter__(self): 32 | return self 33 | 34 | def __exit__(self, type, value, tb): 35 | del self 36 | 37 | @property 38 | def url(self): 39 | time = self._parameters['time'] 40 | timestr = ',{}'.format(time) if time else '' 41 | uri_format = '{url}/{key}/{latitude},{longitude}{timestr}' 42 | return uri_format.format(url=_API_URL, timestr=timestr, **self._parameters) 43 | 44 | def refresh(self, timeout=None, **queries): 45 | self._queries = queries 46 | self.timeout = timeout 47 | request_params = { 48 | 'params': self._queries, 49 | 'headers': {'Accept-Encoding': 'gzip'}, 50 | 'timeout': timeout 51 | } 52 | 53 | response = requests.get(self.url, **request_params) 54 | self.response_headers = response.headers 55 | if response.status_code is not 200: 56 | raise requests.exceptions.HTTPError('Bad response') 57 | return super().__init__(json.loads(response.text)) 58 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | darkskylib 2 | ========== 3 | 4 | This library for the `Dark Sky 5 | API `__ provides access to detailed 6 | weather information from around the globe. 7 | 8 | Quick start 9 | ----------- 10 | 11 | Before you start using this library, you need to get your API key 12 | `here `__. 13 | 14 | 15 | API Calls 16 | ~~~~~~~~~ 17 | 18 | Function ``forecast`` handles all request parameters and returns a 19 | ``Forecast`` object. 20 | 21 | .. code:: python 22 | 23 | >>> from darksky import forecast 24 | >>> boston = forecast(key, 42.3601, -71.0589) 25 | >>> 26 | 27 | The first 3 positional arguments are identical to the 3 required 28 | parameters for API call. The optional query parameters need to be 29 | provided as keyword arguments. 30 | 31 | Using ``time`` argument will get you a **time machine call**. 32 | Using ``timeout`` argument will set default `request timeout `__ . 33 | 34 | .. code:: python 35 | 36 | >>> BOSTON = key, 42.3601, -71.0589 37 | >>> from datetime import datetime as dt 38 | >>> t = dt(2013, 5, 6, 12).isoformat() 39 | >>> boston = forecast(*BOSTON, time=t) 40 | >>> boston.time 41 | 1367866800 42 | 43 | Data Points and Data Blocks 44 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 45 | 46 | The values as well as ``DataPoint`` and ``DataBlock`` objects are 47 | accessed using instance attributes or dictionary keys. You can access 48 | current values directly, without going through ``currently`` data point. 49 | 50 | .. code:: python 51 | 52 | >>> boston['currently']['temperature'] 53 | 60.72 54 | >>> boston.temperature 55 | 60.72 56 | 57 | **Data blocks** are indexable and iterable by their ``data`` values. 58 | 59 | .. code:: python 60 | 61 | >>> len(boston.hourly) 62 | 24 63 | >>> 64 | >>> boston.hourly[1].temperature 65 | 59.49 66 | >>> 67 | >>> # list temperatures for next 10 hours 68 | ... [hour.temperature for hour in boston.hourly[:10]] 69 | [60.83, 59.49, 58.93, 57.95, 56.01, 53.95, 51.21, 49.21, 47.95, 46.31] 70 | 71 | Nonexistent attributes will raise ``AttributeError`` and dictionary keys 72 | ``KeyError`` the way you'd expect. 73 | 74 | Raw data 75 | ~~~~~~~~ 76 | 77 | To get the raw data dictionary, you can either access it through 78 | instance attributes or navigate to it through dictionary keys, the same 79 | way you would navigate the actual dictionary. 80 | 81 | .. code:: python 82 | 83 | >>> boston.hourly[2] 84 | {'ozone': 290.06, 'temperature': 58.93, 'pressure': 1017.8, 'windBearing': 274, 'dewPoint': 52.58, 'cloudCover': 0.29, 'apparentTemperature': 58.93, 'windSpeed': 7.96, 'summary': 'Partly Cloudy', 'icon': 'partly-cloudy-night', 'humidity': 0.79, 'precipProbability': 0, 'precipIntensity': 0, 'visibility': 8.67, 'time': 1476410400} 85 | >>> 86 | >>> boston['hourly']['data'][2] 87 | {'ozone': 290.06, 'temperature': 58.93, 'pressure': 1017.8, 'windBearing': 274, 'dewPoint': 52.58, 'cloudCover': 0.29, 'apparentTemperature': 58.93, 'windSpeed': 7.96, 'summary': 'Partly Cloudy', 'icon': 'partly-cloudy-night', 'humidity': 0.79, 'precipProbability': 0, 'precipIntensity': 0, 'visibility': 8.67, 'time': 1476410400} 88 | 89 | Flags and Alerts 90 | ~~~~~~~~~~~~~~~~ 91 | 92 | All dashes ``-`` in attribute names of **Flags** objects are replaced by 93 | underscores ``_``. This doesn't affect the dictionary keys. 94 | 95 | .. code:: python 96 | 97 | >>> # instead of 'boston.flags.isd-stations' 98 | ... boston.flags.isd_stations 99 | ['383340-99999', '383390-99999', '383410-99999', '384620-99999', '384710-99999'] 100 | >>> 101 | >>> boston.flags['isd-stations'] 102 | ['383340-99999', '383390-99999', '383410-99999', '384620-99999', '384710-99999'] 103 | 104 | Even though **Alerts** are represented by a list, the data accessibility 105 | through instance attributes is preserved for alerts in the list. 106 | 107 | .. code:: python 108 | 109 | >>> boston.alerts[0].title 110 | 'Freeze Watch for Norfolk, MA' 111 | 112 | Updating data 113 | ~~~~~~~~~~~~~ 114 | 115 | Use ``refresh()`` method to update data of a ``Forecast`` object. The 116 | ``refresh()`` method takes optional queries (including ``time``, making 117 | it a **Time machine** object) as keyword arguments. Calling 118 | ``refresh()`` without any arguments will set all queries to default 119 | values. Use ``timeout`` argument to set the request timeout. 120 | 121 | .. code:: python 122 | 123 | >>> boston.refresh() 124 | >>> (boston.time, boston.temperature, len(boston.hourly)) 125 | (1476403500, 60.72, 49) 126 | >>> 127 | >>> boston.refresh(units='si', extend='hourly') 128 | >>> (boston.time, boston.temperature, len(boston.hourly)) 129 | (1476404205, 15.81, 169) 130 | >>> 131 | >>> boston.refresh(units='us') 132 | >>> (boston.time, boston.temperature, len(boston.hourly)) 133 | (1476404489, 60.57, 49) 134 | 135 | For Developers 136 | ~~~~~~~~~~~~~~ 137 | 138 | Response headers are stored in a dictionary under ``response_headers`` 139 | attribute. 140 | 141 | .. code:: python 142 | 143 | >>> boston.response_headers['X-response-Time'] 144 | '146.035ms' 145 | 146 | Example script 147 | -------------- 148 | 149 | .. code:: python 150 | 151 | from darksky import forecast 152 | from datetime import date, timedelta 153 | 154 | BOSTON = 42.3601, 71.0589 155 | 156 | weekday = date.today() 157 | with forecast('API_KEY', *BOSTON) as boston: 158 | print(boston.daily.summary, end='\n---\n') 159 | for day in boston.daily: 160 | day = dict(day = date.strftime(weekday, '%a'), 161 | sum = day.summary, 162 | tempMin = day.temperatureMin, 163 | tempMax = day.temperatureMax 164 | ) 165 | print('{day}: {sum} Temp range: {tempMin} - {tempMax}'.format(**day)) 166 | weekday += timedelta(days=1) 167 | 168 | Output: 169 | 170 | :: 171 | 172 | Light rain on Friday and Saturday, with temperatures bottoming out at 48°F on Tuesday. 173 | --- 174 | Sun: Partly cloudy in the morning. Temp range: 44.86 - 57.26°F 175 | Mon: Mostly cloudy in the morning. Temp range: 44.26 - 55.28°F 176 | Tue: Clear throughout the day. Temp range: 36.85 - 47.9°F 177 | Wed: Partly cloudy starting in the afternoon, continuing until evening. Temp range: 33.23 - 47.93°F 178 | Thu: Light rain overnight. Temp range: 35.75 - 49.71°F 179 | Fri: Light rain in the morning and afternoon. Temp range: 45.47 - 57.11°F 180 | Sat: Drizzle in the morning. Temp range: 43.3 - 62.08°F 181 | Sun: Clear throughout the day. Temp range: 39.81 - 60.84°F 182 | 183 | License 184 | ------- 185 | 186 | The code is available under terms of `MIT 187 | License `__ 188 | -------------------------------------------------------------------------------- /test/response.json: -------------------------------------------------------------------------------- 1 | {"latitude": -77.843906, "longitude": 166.68652, "timezone": "Etc/GMT-11", "currently": {"time": 1523647162, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -23.58, "apparentTemperature": -46.44, "dewPoint": -37.84, "humidity": 0.45, "pressure": 986.6, "windSpeed": 11.26, "windGust": 18.01, "windBearing": 56, "cloudCover": 0.06, "uvIndex": 0, "visibility": 6.22, "ozone": 259.02}, "hourly": {"summary": "Clear throughout the day.", "icon": "clear-day", "data": [{"time": 1523646000, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -22.91, "apparentTemperature": -46.72, "dewPoint": -37.15, "humidity": 0.46, "pressure": 986.52, "windSpeed": 12.49, "windGust": 19.56, "windBearing": 53, "cloudCover": 0.07, "uvIndex": 0, "visibility": 6.22, "ozone": 258.84}, {"time": 1523649600, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -24.99, "apparentTemperature": -45.62, "dewPoint": -39.31, "humidity": 0.45, "pressure": 986.76, "windSpeed": 8.86, "windGust": 14.76, "windBearing": 66, "cloudCover": 0.04, "uvIndex": 0, "visibility": 6.22, "ozone": 259.38}, {"time": 1523653200, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -27.32, "apparentTemperature": -44.87, "dewPoint": -41.48, "humidity": 0.45, "pressure": 986.96, "windSpeed": 6.28, "windGust": 10.04, "windBearing": 92, "cloudCover": 0.01, "uvIndex": 0, "visibility": 6.22, "ozone": 259.92}, {"time": 1523656800, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -28.85, "apparentTemperature": -45.93, "dewPoint": -42.64, "humidity": 0.46, "pressure": 987.08, "windSpeed": 5.83, "windGust": 8.13, "windBearing": 105, "cloudCover": 0, "uvIndex": 0, "visibility": 6.22, "ozone": 260.14}, {"time": 1523660400, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -29.63, "apparentTemperature": -46.72, "dewPoint": -42.81, "humidity": 0.47, "pressure": 987.14, "windSpeed": 5.74, "windGust": 8.52, "windBearing": 97, "cloudCover": 0, "uvIndex": 0, "ozone": 260.37}, {"time": 1523664000, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -30.51, "apparentTemperature": -47, "dewPoint": -43.13, "humidity": 0.48, "pressure": 987.19, "windSpeed": 5.33, "windGust": 8.71, "windBearing": 90, "cloudCover": 0, "uvIndex": 0, "ozone": 261.15}, {"time": 1523667600, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -31.36, "apparentTemperature": -31.36, "dewPoint": -43.58, "humidity": 0.49, "pressure": 987.21, "windSpeed": 2.12, "windGust": 8.5, "windBearing": 96, "cloudCover": 0, "uvIndex": 0, "ozone": 263.17}, {"time": 1523671200, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -32.28, "apparentTemperature": -32.28, "dewPoint": -44.16, "humidity": 0.5, "pressure": 987.21, "windSpeed": 2.33, "windGust": 8.08, "windBearing": 136, "cloudCover": 0, "uvIndex": 0, "ozone": 265.75}, {"time": 1523674800, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -33.1, "apparentTemperature": -33.1, "dewPoint": -44.65, "humidity": 0.51, "pressure": 987.22, "windSpeed": 1.9, "windGust": 7.65, "windBearing": 145, "cloudCover": 0, "uvIndex": 0, "ozone": 267.24}, {"time": 1523678400, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -33.67, "apparentTemperature": -46.67, "dewPoint": -45.13, "humidity": 0.51, "pressure": 987.26, "windSpeed": 3.58, "windGust": 7.31, "windBearing": 105, "cloudCover": 0, "uvIndex": 0, "ozone": 266.51}, {"time": 1523682000, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -34.14, "apparentTemperature": -46.35, "dewPoint": -45.52, "humidity": 0.51, "pressure": 987.3, "windSpeed": 3.28, "windGust": 6.95, "windBearing": 132, "cloudCover": 0, "uvIndex": 0, "ozone": 264.49}, {"time": 1523685600, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -34.56, "apparentTemperature": -34.56, "dewPoint": -46.01, "humidity": 0.51, "pressure": 987.39, "windSpeed": 2.26, "windGust": 6.62, "windBearing": 145, "cloudCover": 0, "uvIndex": 0, "ozone": 263.04}, {"time": 1523689200, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -34.83, "apparentTemperature": -34.83, "dewPoint": -46.49, "humidity": 0.51, "pressure": 987.5, "windSpeed": 1.95, "windGust": 6.29, "windBearing": 157, "cloudCover": 0, "uvIndex": 0, "ozone": 262.55}, {"time": 1523692800, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -34.95, "apparentTemperature": -34.95, "dewPoint": -47, "humidity": 0.49, "pressure": 987.65, "windSpeed": 1.72, "windGust": 5.97, "windBearing": 173, "cloudCover": 0, "uvIndex": 0, "ozone": 262.41}, {"time": 1523696400, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -35.1, "apparentTemperature": -35.1, "dewPoint": -47.64, "humidity": 0.48, "pressure": 987.82, "windSpeed": 1.75, "windGust": 5.79, "windBearing": 181, "cloudCover": 0, "uvIndex": 0, "ozone": 262.82}, {"time": 1523700000, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -35.41, "apparentTemperature": -35.41, "dewPoint": -48.75, "humidity": 0.45, "pressure": 987.98, "windSpeed": 1.18, "windGust": 5.76, "windBearing": 184, "cloudCover": 0, "uvIndex": 0, "ozone": 264.02}, {"time": 1523703600, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -35.96, "apparentTemperature": -35.96, "dewPoint": -50.03, "humidity": 0.43, "pressure": 988.15, "windSpeed": 0.7, "windGust": 5.87, "windBearing": 165, "cloudCover": 0, "uvIndex": 0, "ozone": 265.7}, {"time": 1523707200, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -36.57, "apparentTemperature": -36.57, "dewPoint": -51.11, "humidity": 0.42, "pressure": 988.37, "windSpeed": 1.13, "windGust": 6.04, "windBearing": 154, "cloudCover": 0, "uvIndex": 0, "ozone": 266.8}, {"time": 1523710800, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -36.85, "apparentTemperature": -49.46, "dewPoint": -52.08, "humidity": 0.4, "pressure": 988.67, "windSpeed": 3.29, "windGust": 6.25, "windBearing": 133, "cloudCover": 0, "uvIndex": 0, "ozone": 266.66}, {"time": 1523714400, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -37.11, "apparentTemperature": -37.11, "dewPoint": -52.8, "humidity": 0.39, "pressure": 988.99, "windSpeed": 2.21, "windGust": 6.53, "windBearing": 102, "cloudCover": 0, "uvIndex": 0, "ozone": 265.88}, {"time": 1523718000, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -37.3, "apparentTemperature": -37.3, "dewPoint": -52.89, "humidity": 0.39, "pressure": 989.28, "windSpeed": 0.77, "windGust": 6.92, "windBearing": 162, "cloudCover": 0, "uvIndex": 0, "ozone": 265.21}, {"time": 1523721600, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -37.36, "apparentTemperature": -37.36, "dewPoint": -52.05, "humidity": 0.41, "pressure": 989.47, "windSpeed": 1.19, "windGust": 7.51, "windBearing": 33, "cloudCover": 0.01, "uvIndex": 0, "ozone": 264.89}, {"time": 1523725200, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -37.22, "apparentTemperature": -50.44, "dewPoint": -50.56, "humidity": 0.45, "pressure": 989.6, "windSpeed": 3.47, "windGust": 8.2, "windBearing": 348, "cloudCover": 0.02, "uvIndex": 0, "ozone": 264.69}, {"time": 1523728800, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -36.86, "apparentTemperature": -53.19, "dewPoint": -49.04, "humidity": 0.49, "pressure": 989.73, "windSpeed": 4.72, "windGust": 8.65, "windBearing": 331, "cloudCover": 0.02, "uvIndex": 0, "ozone": 264.74}, {"time": 1523732400, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -36.05, "apparentTemperature": -53.29, "dewPoint": -47.49, "humidity": 0.51, "pressure": 989.88, "windSpeed": 5.21, "windGust": 8.65, "windBearing": 327, "cloudCover": 0.02, "uvIndex": 0, "ozone": 265.19}, {"time": 1523736000, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -35.03, "apparentTemperature": -52.83, "dewPoint": -45.93, "humidity": 0.53, "pressure": 990.01, "windSpeed": 5.58, "windGust": 8.38, "windBearing": 333, "cloudCover": 0.01, "uvIndex": 0, "ozone": 265.96}, {"time": 1523739600, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -34.11, "apparentTemperature": -52.12, "dewPoint": -44.34, "humidity": 0.55, "pressure": 990.09, "windSpeed": 5.79, "windGust": 8.18, "windBearing": 337, "cloudCover": 0, "uvIndex": 0, "ozone": 266.67}, {"time": 1523743200, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -33.39, "apparentTemperature": -51.29, "dewPoint": -42.77, "humidity": 0.58, "pressure": 990.09, "windSpeed": 5.8, "windGust": 8.13, "windBearing": 334, "cloudCover": 0, "uvIndex": 0, "ozone": 267.26}, {"time": 1523746800, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -32.69, "apparentTemperature": -50.33, "dewPoint": -41.24, "humidity": 0.61, "pressure": 990.02, "windSpeed": 5.74, "windGust": 8.13, "windBearing": 329, "cloudCover": 0, "uvIndex": 0, "ozone": 267.93}, {"time": 1523750400, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -32.11, "apparentTemperature": -50.17, "dewPoint": -39.85, "humidity": 0.64, "pressure": 989.95, "windSpeed": 6.03, "windGust": 8.12, "windBearing": 330, "cloudCover": 0, "uvIndex": 0, "ozone": 268.68}, {"time": 1523754000, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -31.6, "apparentTemperature": -50.45, "dewPoint": -38.75, "humidity": 0.67, "pressure": 989.86, "windSpeed": 6.55, "windGust": 8.23, "windBearing": 345, "cloudCover": 0, "uvIndex": 0, "ozone": 269.7}, {"time": 1523757600, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -31.2, "apparentTemperature": -46.38, "dewPoint": -37.83, "humidity": 0.69, "pressure": 989.76, "windSpeed": 4.63, "windGust": 8.33, "windBearing": 313, "cloudCover": 0, "uvIndex": 0, "ozone": 270.83}, {"time": 1523761200, "summary": "Clear", "icon": "clear-day", "precipIntensity": 0, "precipProbability": 0, "temperature": -30.7, "apparentTemperature": -48.52, "dewPoint": -37.13, "humidity": 0.7, "pressure": 989.68, "windSpeed": 6.05, "windGust": 8.18, "windBearing": 325, "cloudCover": 0, "uvIndex": 0, "ozone": 271.96}, {"time": 1523764800, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -30.01, "apparentTemperature": -47.82, "dewPoint": -36.73, "humidity": 0.69, "pressure": 989.66, "windSpeed": 6.12, "windGust": 7.56, "windBearing": 331, "cloudCover": 0, "uvIndex": 0, "ozone": 272.89}, {"time": 1523768400, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -29.33, "apparentTemperature": -46.67, "dewPoint": -36.61, "humidity": 0.66, "pressure": 989.65, "windSpeed": 5.92, "windGust": 6.86, "windBearing": 338, "cloudCover": 0, "uvIndex": 0, "ozone": 273.7}, {"time": 1523772000, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -28.9, "apparentTemperature": -45.32, "dewPoint": -36.63, "humidity": 0.65, "pressure": 989.66, "windSpeed": 5.45, "windGust": 6.72, "windBearing": 341, "cloudCover": 0, "uvIndex": 0, "ozone": 274.42}, {"time": 1523775600, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -28.8, "apparentTemperature": -44.51, "dewPoint": -36.93, "humidity": 0.63, "pressure": 989.66, "windSpeed": 5.09, "windGust": 6.39, "windBearing": 342, "cloudCover": 0, "uvIndex": 0, "ozone": 274.99}, {"time": 1523779200, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -28.95, "apparentTemperature": -43.83, "dewPoint": -37.37, "humidity": 0.62, "pressure": 989.68, "windSpeed": 4.67, "windGust": 5.94, "windBearing": 339, "cloudCover": 0, "uvIndex": 0, "ozone": 275.47}, {"time": 1523782800, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -29.04, "apparentTemperature": -43.37, "dewPoint": -37.82, "humidity": 0.61, "pressure": 989.79, "windSpeed": 4.41, "windGust": 5.61, "windBearing": 337, "cloudCover": 0, "uvIndex": 0, "ozone": 275.84}, {"time": 1523786400, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -28.78, "apparentTemperature": -43.28, "dewPoint": -38.28, "humidity": 0.59, "pressure": 990, "windSpeed": 4.5, "windGust": 5.47, "windBearing": 339, "cloudCover": 0, "uvIndex": 0, "ozone": 275.9}, {"time": 1523790000, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -28.47, "apparentTemperature": -42.94, "dewPoint": -38.78, "humidity": 0.56, "pressure": 990.31, "windSpeed": 4.52, "windGust": 5.45, "windBearing": 339, "cloudCover": 0, "uvIndex": 0, "ozone": 275.81}, {"time": 1523793600, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -28.05, "apparentTemperature": -42.33, "dewPoint": -39.16, "humidity": 0.53, "pressure": 990.68, "windSpeed": 4.46, "windGust": 5.42, "windBearing": 336, "cloudCover": 0, "uvIndex": 0, "ozone": 275.65}, {"time": 1523797200, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -27.61, "apparentTemperature": -27.61, "dewPoint": -39.35, "humidity": 0.52, "pressure": 991.13, "windSpeed": 2.69, "windGust": 5.68, "windBearing": 322, "cloudCover": 0, "uvIndex": 0, "ozone": 275.52}, {"time": 1523800800, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -27.25, "apparentTemperature": -43.04, "dewPoint": -39.28, "humidity": 0.51, "pressure": 991.66, "windSpeed": 5.27, "windGust": 6.52, "windBearing": 350, "cloudCover": 0, "uvIndex": 0, "ozone": 275.3}, {"time": 1523804400, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -26.78, "apparentTemperature": -41.64, "dewPoint": -39.06, "humidity": 0.5, "pressure": 992.17, "windSpeed": 4.84, "windGust": 7.17, "windBearing": 326, "cloudCover": 0, "uvIndex": 0, "ozone": 275.01}, {"time": 1523808000, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -25.98, "apparentTemperature": -40.28, "dewPoint": -38.14, "humidity": 0.51, "pressure": 992.62, "windSpeed": 4.63, "windGust": 7.39, "windBearing": 319, "cloudCover": 0, "uvIndex": 0, "ozone": 274.57}, {"time": 1523811600, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -24.87, "apparentTemperature": -39.11, "dewPoint": -37.07, "humidity": 0.51, "pressure": 993.06, "windSpeed": 4.69, "windGust": 7.36, "windBearing": 319, "cloudCover": 0, "uvIndex": 0, "ozone": 274}, {"time": 1523815200, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -24.16, "apparentTemperature": -38.67, "dewPoint": -36.27, "humidity": 0.51, "pressure": 993.54, "windSpeed": 4.89, "windGust": 7.14, "windBearing": 325, "cloudCover": 0, "uvIndex": 0, "ozone": 273.43}, {"time": 1523818800, "summary": "Clear", "icon": "clear-night", "precipIntensity": 0, "precipProbability": 0, "temperature": -24.13, "apparentTemperature": -39.28, "dewPoint": -36.01, "humidity": 0.52, "pressure": 994.06, "windSpeed": 5.23, "windGust": 6.66, "windBearing": 350, "cloudCover": 0, "uvIndex": 0, "ozone": 272.88}]}, "daily": {"summary": "Light snow (1\u20133 in.) next Saturday, with high temperatures rising to 2\u00b0F next Saturday.", "icon": "snow", "data": [{"time": 1523624400, "summary": "Clear throughout the day.", "icon": "clear-day", "sunriseTime": 1523656200, "sunsetTime": 1523678363, "moonPhase": 0.93, "precipIntensity": 0, "precipIntensityMax": 0.0001, "precipIntensityMaxTime": 1523631600, "precipProbability": 0, "temperatureHigh": -24.99, "temperatureHighTime": 1523649600, "temperatureLow": -37.36, "temperatureLowTime": 1523721600, "apparentTemperatureHigh": -31.36, "apparentTemperatureHighTime": 1523667600, "apparentTemperatureLow": -53.29, "apparentTemperatureLowTime": 1523732400, "dewPoint": -43.9, "humidity": 0.47, "pressure": 987.06, "windSpeed": 3.52, "windGust": 21.82, "windGustTime": 1523642400, "windBearing": 100, "cloudCover": 0.01, "uvIndex": 0, "uvIndexTime": 1523624400, "ozone": 262.59, "temperatureMin": -36.57, "temperatureMinTime": 1523707200, "temperatureMax": -22.1, "temperatureMaxTime": 1523642400, "apparentTemperatureMin": -47, "apparentTemperatureMinTime": 1523664000, "apparentTemperatureMax": -31.36, "apparentTemperatureMaxTime": 1523667600}, {"time": 1523710800, "summary": "Clear throughout the day.", "icon": "clear-day", "sunriseTime": 1523743166, "sunsetTime": 1523764167, "moonPhase": 0.96, "precipIntensity": 0, "precipIntensityMax": 0.0002, "precipIntensityMaxTime": 1523761200, "precipProbability": 0, "temperatureHigh": -28.8, "temperatureHighTime": 1523775600, "temperatureLow": -29.04, "temperatureLowTime": 1523782800, "apparentTemperatureHigh": -43.83, "apparentTemperatureHighTime": 1523779200, "apparentTemperatureLow": -43.37, "apparentTemperatureLowTime": 1523782800, "dewPoint": -42.63, "humidity": 0.56, "pressure": 989.76, "windSpeed": 4.14, "windGust": 8.65, "windGustTime": 1523728800, "windBearing": 337, "cloudCover": 0, "uvIndex": 0, "uvIndexTime": 1523710800, "ozone": 270.04, "temperatureMin": -37.36, "temperatureMinTime": 1523721600, "temperatureMax": -28.05, "temperatureMaxTime": 1523793600, "apparentTemperatureMin": -53.29, "apparentTemperatureMinTime": 1523732400, "apparentTemperatureMax": -37.11, "apparentTemperatureMaxTime": 1523714400}, {"time": 1523797200, "summary": "Clear throughout the day.", "icon": "clear-day", "sunriseTime": 1523830157, "sunsetTime": 1523849948, "moonPhase": 0.01, "precipIntensity": 0, "precipIntensityMax": 0.0002, "precipIntensityMaxTime": 1523840400, "precipProbability": 0, "temperatureHigh": -24.46, "temperatureHighTime": 1523822400, "temperatureLow": -29.35, "temperatureLowTime": 1523869200, "apparentTemperatureHigh": -24.46, "apparentTemperatureHighTime": 1523822400, "apparentTemperatureLow": -42.64, "apparentTemperatureLowTime": 1523894400, "dewPoint": -39.21, "humidity": 0.5, "pressure": 997.54, "windSpeed": 2.21, "windGust": 7.39, "windGustTime": 1523808000, "windBearing": 337, "cloudCover": 0, "uvIndex": 0, "uvIndexTime": 1523797200, "ozone": 267.49, "temperatureMin": -29.35, "temperatureMinTime": 1523869200, "temperatureMax": -24.13, "temperatureMaxTime": 1523818800, "apparentTemperatureMin": -43.04, "apparentTemperatureMinTime": 1523800800, "apparentTemperatureMax": -24.46, "apparentTemperatureMaxTime": 1523822400}, {"time": 1523883600, "summary": "Partly cloudy throughout the day.", "icon": "partly-cloudy-night", "sunriseTime": 1523917176, "sunsetTime": 1523935701, "moonPhase": 0.03, "precipIntensity": 0, "precipIntensityMax": 0, "precipProbability": 0, "temperatureHigh": -18.66, "temperatureHighTime": 1523952000, "temperatureLow": -22.06, "temperatureLowTime": 1523998800, "apparentTemperatureHigh": -18.66, "apparentTemperatureHighTime": 1523952000, "apparentTemperatureLow": -28.19, "apparentTemperatureLowTime": 1523980800, "dewPoint": -34.34, "humidity": 0.55, "pressure": 1004.68, "windSpeed": 3.55, "windGust": 7.63, "windGustTime": 1523912400, "windBearing": 314, "cloudCover": 0.36, "uvIndex": 0, "uvIndexTime": 1523883600, "ozone": 243.82, "temperatureMin": -29.27, "temperatureMinTime": 1523898000, "temperatureMax": -16.94, "temperatureMaxTime": 1523966400, "apparentTemperatureMin": -42.64, "apparentTemperatureMinTime": 1523894400, "apparentTemperatureMax": -16.94, "apparentTemperatureMaxTime": 1523966400}, {"time": 1523970000, "summary": "Partly cloudy starting in the afternoon, continuing until evening.", "icon": "partly-cloudy-night", "sunriseTime": 1524004230, "sunsetTime": 1524021420, "moonPhase": 0.07, "precipIntensity": 0, "precipIntensityMax": 0, "precipProbability": 0, "temperatureHigh": -19.56, "temperatureHighTime": 1524013200, "temperatureLow": -33.13, "temperatureLowTime": 1524085200, "apparentTemperatureHigh": -19.56, "apparentTemperatureHighTime": 1524013200, "apparentTemperatureLow": -53.88, "apparentTemperatureLowTime": 1524085200, "dewPoint": -31.53, "humidity": 0.56, "pressure": 994.53, "windSpeed": 1.4, "windGust": 10.61, "windGustTime": 1524052800, "windBearing": 113, "cloudCover": 0.28, "uvIndex": 0, "uvIndexTime": 1523970000, "ozone": 261.79, "temperatureMin": -25.2, "temperatureMinTime": 1524052800, "temperatureMax": -16.83, "temperatureMaxTime": 1523970000, "apparentTemperatureMin": -42.61, "apparentTemperatureMinTime": 1524052800, "apparentTemperatureMax": -16.83, "apparentTemperatureMaxTime": 1523970000}, {"time": 1524056400, "summary": "Clear throughout the day.", "icon": "clear-day", "sunriseTime": 1524091329, "sunsetTime": 1524107096, "moonPhase": 0.11, "precipIntensity": 0, "precipIntensityMax": 0.0001, "precipIntensityMaxTime": 1524106800, "precipProbability": 0, "temperatureHigh": -31.8, "temperatureHighTime": 1524081600, "temperatureLow": -36.67, "temperatureLowTime": 1524128400, "apparentTemperatureHigh": -49.52, "apparentTemperatureHighTime": 1524124800, "apparentTemperatureLow": -51.21, "apparentTemperatureLowTime": 1524139200, "dewPoint": -39.39, "humidity": 0.68, "pressure": 998.28, "windSpeed": 5.05, "windGust": 15.99, "windGustTime": 1524106800, "windBearing": 107, "cloudCover": 0, "uvIndex": 0, "uvIndexTime": 1524056400, "ozone": 279.72, "temperatureMin": -36.68, "temperatureMinTime": 1524124800, "temperatureMax": -25.39, "temperatureMaxTime": 1524056400, "apparentTemperatureMin": -56.77, "apparentTemperatureMinTime": 1524114000, "apparentTemperatureMax": -26.16, "apparentTemperatureMaxTime": 1524063600}, {"time": 1524142800, "summary": "Partly cloudy throughout the day.", "icon": "partly-cloudy-night", "sunriseTime": 1524178485, "sunsetTime": 1524192715, "moonPhase": 0.14, "precipIntensity": 0, "precipIntensityMax": 0.0001, "precipIntensityMaxTime": 1524204000, "precipProbability": 0, "temperatureHigh": -25.95, "temperatureHighTime": 1524211200, "temperatureLow": -24.45, "temperatureLowTime": 1524214800, "apparentTemperatureHigh": -45.72, "apparentTemperatureHighTime": 1524211200, "apparentTemperatureLow": -43.7, "apparentTemperatureLowTime": 1524214800, "dewPoint": -33.27, "humidity": 0.82, "pressure": 994.23, "windSpeed": 6.77, "windGust": 12.49, "windGustTime": 1524225600, "windBearing": 22, "cloudCover": 0.32, "uvIndex": 0, "uvIndexTime": 1524142800, "ozone": 296.24, "temperatureMin": -32.99, "temperatureMinTime": 1524142800, "temperatureMax": -21.61, "temperatureMaxTime": 1524225600, "apparentTemperatureMin": -52.15, "apparentTemperatureMinTime": 1524189600, "apparentTemperatureMax": -33.61, "apparentTemperatureMaxTime": 1524225600}, {"time": 1524229200, "summary": "Mostly cloudy throughout the day and dangerously windy starting in the evening.", "icon": "wind", "sunriseTime": 1524265719, "sunsetTime": 1524278256, "moonPhase": 0.18, "precipIntensity": 0.005, "precipIntensityMax": 0.0115, "precipIntensityMaxTime": 1524283200, "precipProbability": 0.04, "precipAccumulation": 2.275, "precipType": "snow", "temperatureHigh": 2.08, "temperatureHighTime": 1524283200, "temperatureLow": -7.43, "temperatureLowTime": 1524326400, "apparentTemperatureHigh": -12.17, "apparentTemperatureHighTime": 1524279600, "apparentTemperatureLow": -28.75, "apparentTemperatureLowTime": 1524326400, "dewPoint": -10.7, "humidity": 0.83, "pressure": 986.05, "windSpeed": 6.4, "windGust": 49.33, "windGustTime": 1524312000, "windBearing": 153, "cloudCover": 0.86, "uvIndex": 0, "uvIndexTime": 1524229200, "ozone": 293.23, "temperatureMin": -19.86, "temperatureMinTime": 1524229200, "temperatureMax": 2.08, "temperatureMaxTime": 1524283200, "apparentTemperatureMin": -35.71, "apparentTemperatureMinTime": 1524229200, "apparentTemperatureMax": -12.17, "apparentTemperatureMaxTime": 1524279600}]}, "flags": {"sources": ["isd", "cmc", "gfs", "madis"], "isd-stations": ["896630-99999", "896640-99999", "896660-99999", "896670-99999", "896680-99999", "896690-99999", "896700-99999", "896740-87601", "896740-99999", "897680-99999", "897690-99999", "898650-99999", "898660-99999", "898720-99999", "999999-87601"], "units": "us"}, "offset": 11} --------------------------------------------------------------------------------