from json import loads
from pendulum import parse
from requests import get
from os import environ
json.load()
takes theread_file
object and returns the json object which contains the weather data from Timeline APIpendulum.parse()
method is used to parse formatted strings based on ISO 8601requests.get()
sends a GET request to the URLos.environ()
maps environmental variables as a dictionary
pendulum.parse()
example: {grn}Time{res} {parse(cc['datetime']).format('h:mm A')}
red = '\x1b[31m'
grn = '\x1b[32m'
blu = '\x1b[34m'
res = '\x1b[0m'
The color format variables above help to keep cryptic text-formatting codes out of view and make associated f-strings appear more human-readable to coders (see Print Data to Terminal section):
{grn}Time{res} {parse(cc['datetime']).format('h:mm A')}
response = get(f'https://weather.visualcrossing.com/\
VisualCrossingWebServices/rest/services/timeline/{environ["GEO_COORDS"]}\
?key={environ["TIMELINE_API_KEY"]}').text
data = loads(response)
This object accesses sunrise
data: data['currentConditions']['sunrise']
The two environmental variables in the URL above can be stored in the /etc/environment
file which can be accessed using the os.environ()
method.
The following is an example of how to print weather data for current conditions to the terminal emulator display. Such multi-line f-strings were used to minimize excessive print calls.
current_conditions = data['currentConditions']
print(f'''\
{grn}Time{res} {parse(current_conditions['datetime']).format('h:mm A')}
{grn}Description{res} {current_conditions['conditions']}
{grn}Temperature{res} {current_conditions['temp']}℉
{grn}Feels like{res} {current_conditions['feelslike']}℉
{grn}Humidity{res} {current_conditions['humidity']}%
{grn}Dew point{res} {current_conditions['dew']}℉
{grn}Precipitation{res} {current_conditions['precip']}
{grn}Precip. prob.{res} {current_conditions['precipprob']}
{grn}Snow{res} {current_conditions['snow']}
{grn}Snow depth{res} {current_conditions['snowdepth']}
{grn}Precip. type{res} {current_conditions['preciptype']}
{grn}Wind gust{res} {current_conditions['windgust']}
{grn}Wind speed{res} {current_conditions['windspeed']}
{grn}Wind Direction{res} {current_conditions['winddir']}
{grn}Air pressure{res} {current_conditions['pressure']}
{grn}Visibility{res} {current_conditions['visibility']}mi
{grn}Cloud cover{res} {current_conditions['cloudcover']}
{grn}UV index{res} {current_conditions['uvindex']}
{grn}Sunrise{res} {parse(data['currentConditions']['sunrise']).format('h:mm A')}
{grn}Sunset{res} {parse(data['currentConditions']['sunset']).format('h:mm A')}
{grn}Moon phase{res} {current_conditions['moonphase']}''')
On days during which there are no weather alerts, a try/except block can be used to handle any IndexError
which occurs.
try:
alerts = data['alerts'][0]
ends = parse(alerts['ends'])
print(f'''\
{red}Alerts{res} {alerts['event'].upper()}
{red}Headline{res}\n{alerts['headline']}
{red}Description{res}\n{alerts['description']}
{red}Ends{res} {ends.format('dddd D MMMM YYYY hh:mm A')}
{blu}========= CURRENT =========={res}''')
except IndexError:
print(f'''There are no alerts at this time.
{blu}========= CURRENT =========={res}''')
To include all 16 cardinal wind directions, a 360 degree circle is cut into 16 x 22.5% slices.
cardinal = ['N', 'NNE', 'NE', 'ENE', 'E', 'ESE', 'SE', 'SSE',
'S', 'SSW', 'SW', 'WSW', 'W', 'WNW', 'NW', 'NNW']
wind_dir = cardinal[int(day['winddir']/22.5)]
The Gist for this project is linked to the following...
https://gist.github.com/nick3499/10aa037bab43dbcc0072be739aa0744c
...which may or may not be updated to current version.
Used the Timeline Weather API for weather data