{"id":1988,"date":"2019-05-31T18:32:43","date_gmt":"2019-05-31T18:32:43","guid":{"rendered":"https:\/\/www.codeastar.com\/?p=1988"},"modified":"2019-12-28T05:47:12","modified_gmt":"2019-12-28T05:47:12","slug":"easy-accuweather-forecast-in-python","status":"publish","type":"post","link":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/","title":{"rendered":"Easy AccuWeather Forecast in Python"},"content":{"rendered":"\n

We have talked different topics in CodeAStar here, ranging from AWS<\/a>, CNN<\/a>, Docker<\/a>, LGB<\/a>, Raspberry Pi<\/a>, RNN<\/a> and the list goes on. Do you know what is the most popular page here? According to the figure from Google Analytics<\/a>, and out of my expectation, the most popular page is “Easy Weather Forecast Tool in Python<\/a>“. In that page, we talked about using Dark Sky API<\/a> to make an easy Python program for weather forecast. So this time, let’s do another weather forecast again. Our weather API to use, will be the high profiling and one of the most accurate weather forecasts — AccuWeather. <\/p>\n\n\n\n\n\n\n\n

Forecast the Weather Forecast Program<\/h3>\n\n\n\n

Before we start making our weather forecast program, we should forecast what will our program look like. First things first, let’s go to AccuWeather APIs website<\/a> to get a free <\/strong>developer account. After that, we can take a look on their API reference<\/a> to see what outputs they can provide.<\/p>\n\n\n\n

The AccuWeather API allows current date and its designed N-day weather forecast submissions. Unlike the Dark Sky API, which we can submit any date range for weather forecast. We also find that the AccuWeather API use an unique location key as input. And the location key is assigned from AccuWeather rather than using longitude and latitude values. Then another important fact we need to know is — we have 50 calls a day for a free account.<\/p>\n\n\n\n

Let’ sum up our findings so far:<\/p>\n\n\n\n

  1. the API only allows certain day ranges as inputs<\/li>
  2. each forecast call needs a location key id<\/li>
  3. we have 50 free API calls per day<\/li><\/ol>\n\n\n\n

    And we expect our work flow would be: <\/p>\n\n\n\n

    \"AccuWeather<\/figure><\/div>\n\n\n\n

    It seems that we need at least 2 API calls (one for location key and one for weather information), to make a weather forecast. And we have only 50 free calls per day… Is there anyway to reduce the number of API calls? <\/p>\n\n\n\n

    A Tiny DB<\/h3>\n\n\n\n

    Yes, we have a solution. Once we got a location key, we store it in our side. So we don’t need to call AccuWeather again for the same location. Then what we need is a database (DB) to store and search the keys. But isn’t installing a DB for our tiny weather program a little bit over? Yes, if you are talking about DBs like MySQL<\/a>, MongoDB<\/a>, Microsoft SQL Server….. However, we only need a tiny DB to run search, save and load functions. Then it is not an issue at all. As we have TinyDB<\/a>. <\/p>\n\n\n\n

    TinyDB is a NoSQL document based DB written in Python. You can think about using a MongoDB which is small and no installation needed. We just need to include it in our package then import it to our code to use it. Now the problem is solved, let’s get ready to rumble!<\/p>\n\n\n\n

    AccuWeather Forecast Development<\/h3>\n\n\n\n

    First, we set up our environment using the good o’ pipenv<\/a> tool: <\/p>\n\n\n\n

    $pipenv --three\n$pipenv shell\n$pipenv install requests\n$pipenv install tinydb<\/code><\/pre>\n\n\n\n

    Create a “accuw_forecast.py” file and import following libraries: <\/p>\n\n\n\n

    from tinydb import TinyDB, Query\nimport requests\nimport json, re, sys, argparse, os\nfrom datetime import datetime<\/pre>\n\n\n\n

    Then we create a database, “accuw_db.json<\/em>” for our program. Yes, the db is actually a JSON file. We have 2 tables here, “Location<\/em>” is a table storing location keys. Another table, “Profile<\/em>“, is a table storing our API key and metric unit.<\/p>\n\n\n\n

    db = TinyDB('accuw_db.json')\nLocation = db.table('Location')\nProfile = db.table('Profile')\n<\/pre>\n\n\n\n

    The program will try to load the AccuWeather API key from environment variable “ACW_API_KEY<\/em>“. Then it will update the API key in our Profile<\/em> table.<\/p>\n\n\n\n

    if \"ACW_API_KEY\" in os.environ:\n    API_KEY = os.environ['ACW_API_KEY']   \n    Profile.upsert({'api_key':API_KEY}, Query().api_key.exists())\nelse: \n    API_KEY = Profile.search(Query().api_key)\n    if API_KEY == []: \n      sys.exit(\"No API key found\")\n    API_KEY = API_KEY[0]['api_key']\n<\/pre>\n\n\n\n

    For location and metric unit, we can enter them from command line arguments. The program will store them to Profile<\/em> table. Then we don’t need to enter them again, unless you want to change to other location\/metric unit.<\/p>\n\n\n\n

    def is_input_inputted(input_var, table, field_name):\n  if input_var is None: \n    input_var = table.search(Query()[field_name])\n    if input_var == []: \n      parser.print_help()\n      sys.exit()\n    input_var = input_var[0][field_name]  \n  else: \n    table.upsert({field_name:input_var}, Query()[field_name].exists())\n  return input_var\n\nparser = argparse.ArgumentParser(description='AccuWeather Forecast for Python')\nparser.add_argument('-l', action=\"store\", dest=\"location\",  help='location for weather forecast, e.g. \"Tokyo\"') \nparser.add_argument('-m', action=\"store\", dest=\"metric\", choices=['c', 'f'], help='metric for weather forecast, c or f', default=\"c\", type=str.lower )\nargs = parser.parse_args()\n\nlocation = is_input_inputted(args.location,Profile, \"last_location\")     \nmetric = is_input_inputted(args.metric, Profile, \"last_metric\")   \n<\/pre>\n\n\n\n

    How location works? <\/h3>\n\n\n\n

    We have an idea to store location key for each weather forecast call. It can reduce the number of calls if we forecast the same single location. But what if we try to forecast different locations? It still requires many API calls. Don’t panic, we have another idea. <\/p>\n\n\n\n

    When we run our AccuWeather program (ACW) for the first time, we can make an API call to get the 150 most popular locations from AccuWeather.com. We then capture their names, administrative areas and countries. So no more extra call is needed, if we try to forecast those locations. Please note that administrative areas are used to identify the same locations in different places. You can think about the case of “Springfield, New Jersey” and “Springfield, Illinois” and “Springfield, The Simpsons”<\/s>.<\/p>\n\n\n\n

    def getJSONfromUrl(url): \n  response = requests.get(url)\n  json_data = json.loads(response.text)\n  return json_data\n\nif (Location.count(Query()) == 0): \n  url = f\"http:\/\/dataservice.accuweather.com\/locations\/v1\/topcities\/150?apikey={API_KEY}\"\n  json_data = getJSONfromUrl(url)\n    \n  for p in json_data:\n    Location.insert({'name': p['LocalizedName'], 'key': p['Key'], 'english_name':p['EnglishName'],\n    'administrative_area':p['AdministrativeArea']['ID'], 'country': p['Country']['EnglishName']})\n<\/pre>\n\n\n\n

    After that, the ACW will first search the location from our local DB, then it will return the location key. If no key is found, it will make an API call to get the location key then store it in our DB.<\/p>\n\n\n\n

    location_from_db = Location.search(Query().name.matches(location, flags=re.IGNORECASE))\n  \nif location_from_db == []:\n  url = f\"http:\/\/dataservice.accuweather.com\/locations\/v1\/search?apikey={API_KEY}&q={location}\"\n  json_data = getJSONfromUrl(url)\nif json_data == []:\n  sys.exit(f\"No location found for '{location}' from AccuWeather API\") \nelse:\n  for p in json_data:\n     Location.insert({'name': location, 'key': p['Key'], 'english_name':p['EnglishName'],\n     'administrative_area':p['AdministrativeArea']['ID'],'country': p['Country']['EnglishName']})\n     break\n  location_from_db = Location.search(Location.name.matches(location, flags=re.IGNORECASE))\n\nlocation_key = location_from_db[0]['key']\nadmin_area = location_from_db[0]['administrative_area']\ncountry = location_from_db[0]['country']\n<\/pre>\n\n\n\n

    Get the Weather<\/h3>\n\n\n\n

    Now we have the location key, we can use it to call the weather forecast APIs. Since there are different forecast APIs<\/a>, ranging from current date, 1-hour, 1-day, 72-hour, 5-day, 10-day…. We pick the APIs that suit us best. Of course we need to know the current weather info, so we pick the current date API. And for the next n-day forecast, I think 5-day is good enough for accuracy and effectiveness.<\/p>\n\n\n\n

    The next thing we need to do is finding which attributes to display in our ACW. Again, there are many weather attributes<\/a> as well. We pick maximum and minimum temperatures, weather description, raining possibility and wind speed as our major info to show in the ACW. You can add or remove info later. Please note that, wind speed is selected because of the wind chill<\/a> effect. TL;DR, faster wind speed blows out warm air around our skin. We then use more energy to cover the heat loss. Thus windier makes us feel<\/em> cooler. Okay, let’s focus back on our code, first we print out the current weather info: <\/p>\n\n\n\n

    def getFormattedDateTime(datestr):\n  p_datestr_format = ''.join(datestr.rsplit(\":\", 1))\n  date_object = datetime.strptime(p_datestr_format, '%Y-%m-%dT%H:%M:%S%z')\n  return date_object.strftime(\"%H:%M %A, %d %B %Y Timezone:%z\")\n\nurl = f\"http:\/\/dataservice.accuweather.com\/currentconditions\/v1\/{location_key}?apikey={API_KEY}&details=true\"\njson_data = getJSONfromUrl(url)\nunit = \"Metric\" if (metric == \"c\") else \"Imperial\"\nmetric_tag = \"true\" if (metric == \"c\") else \"false\"\n\nfor p in json_data:\n  current_weather=p[\"WeatherText\"]\n  current_temp=p[\"Temperature\"][unit]\n  wind_speed=p[\"Wind\"][\"Speed\"][unit]\n  date_w_format = getFormattedDateTime(p[\"LocalObservationDateTime\"])\n\nchar_length = 50\nprint(f\"Location: {location}, {admin_area}, {country}\") \nprint(f\"Local observation time: {date_w_format}\")\nprint(f\"Current weather status: {current_weather}\")\nprint(f\"Current temperature: {current_temp['Value']} {current_temp['Unit']}\")\nprint(f\"Wind speed: {wind_speed['Value']} {wind_speed['Unit']}\")\nprint(f\"\\n{'='*char_length}\")\n<\/pre>\n\n\n\n

    When we use “Los Angeles” as forecast location, <\/p>\n\n\n\n

    $export ACW_API_KEY=abcde\n$python accuw_forecast.py -l \"Los Angeles\" -m c<\/code><\/pre>\n\n\n\n

    It should print out: <\/p>\n\n\n\n

    Location: Los Angeles, CA, United States\nLocal observation time: 02:23 Friday, 31 May 2019 Timezone:-0700\nCurrent weather status: Cloudy\nCurrent temperature: 15.6 C\nWind speed: 5.6 km\/h<\/code><\/pre>\n\n\n\n

    It looks good and the 5-day forecast part is similar to the the current weather part: <\/p>\n\n\n\n

    url = f\"http:\/\/dataservice.accuweather.com\/forecasts\/v1\/daily\/5day\/{location_key}?apikey={API_KEY}&details=true&metric={metric_tag}\"\njson_data = getJSONfromUrl(url)\n\nprint(f\"5-day summery: {json_data['Headline']['Text']}\")\nfor d in json_data[\"DailyForecasts\"]:\n  print(f\"{'-'*char_length}\")\n  print(f\"Date: {getFormattedDateTime( d['Date'])}\")\n  print(f\"Min temperature: {d['Temperature']['Minimum']['Value']} {d['Temperature']['Minimum']['Unit']}\")\n  print(f\"Max temperature: {d['Temperature']['Maximum']['Value']} {d['Temperature']['Maximum']['Unit']}\")\n  print(f\"Description: {d['Day']['LongPhrase']}\")\n  print(f\"Rain probability: {d['Day']['RainProbability']} %\")\n  print(f\"Wind speed: {d['Day']['Wind']['Speed']['Value']} {d['Day']['Wind']['Speed']['Unit']}\")\n<\/pre>\n\n\n\n

    And our output should look like: <\/p>\n\n\n\n

    ==================================================\n5-day summery: Mostly cloudy this weekend\n--------------------------------------------------\nDate: 07:00 Friday, 31 May 2019 Timezone:-0700\nMin temperature: 13.9 C\nMax temperature: 22.2 C\nDescription: Low clouds giving way to sunshine\nRain probability: 4 %\nWind speed: 9.7 km\/h\n--------------------------------------------------\nDate: 07:00 Saturday, 01 June 2019 Timezone:-0700\nMin temperature: 13.9 C\nMax temperature: 21.1 C\nDescription: Low clouds followed by some sun\nRain probability: 10 %\nWind speed: 9.7 km\/h\n......<\/code><\/pre>\n\n\n\n

    That’s it! We’ve just finished another weather forecast program. Then we go for our next topic— Quality Assurance.<\/p>\n\n\n\n

    Quality Assurance on AccuWeather program<\/h3>\n\n\n\n

    We believe everyone codes in the future, no matter it is coded by human or A.I.. In order to code better than others, we run quality assurance to make good our products. Then it comes up another question, what is quality assurance? <\/p>\n\n\n\n

    Quality assurance (QA) is a set of processes to ensure our products meet requirements. It is including but not limited to testing. It can be applied to the planning stage of the Software Development Life Cycle (SDLC). Do you remember we think about getting bulk locations from the first ACW run? And the case to avoid forecasting locations with the same name? <\/p>\n\n\n\n

    Yes, those are processes of QA to ensure the program is robust. We also include wind speed in the ACW to let users consider the wind chill factor. We should document those QA processes, so we can apply the pattern for similar projects.<\/p>\n\n\n\n

    Since we are running QA, why don’t we test our program once again? This time, just run the program without arguments, to test the Profile<\/em> functionality. <\/p>\n\n\n\n

    $python accuw_forecast.py<\/code><\/pre>\n\n\n\n

    Then it should print out:<\/p>\n\n\n\n

    Location: Los Angeles, CA, United States\nLocal observation time: 10:53 Friday, 31 May 2019 Timezone:-0\nCurrent weather status: Cloudy\nCurrent temperature: 18.3 C\nWind speed: 0.0 km\/h\n\n==================================================\n5-day summery: Mostly cloudy this weekend\n--------------------------------------------------\nDate: 07:00 Friday, 31 May 2019 Timezone:-0700\nMin temperature: 14.4 C\nMax temperature: 22.8 C\nDescription: Low clouds giving way to sunshine\nRain probability: 4 %\nWind speed: 6.4 km\/h\n--------------------------------------------------\nDate: 07:00 Saturday, 01 June 2019 Timezone:-0700\nMin temperature: 13.9 C\nMax temperature: 21.1 C\nDescription: Low clouds followed by some sun\nRain probability: 10 %\nWind speed: 9.7 km\/h\n--------------------------------------------------\nDate: 07:00 Sunday, 02 June 2019 Timezone:-0700\nMin temperature: 14.4 C\nMax temperature: 21.1 C\nDescription: Low clouds followed by some sun\nRain probability: 12 %\nWind speed: 9.7 km\/h\n--------------------------------------------------\nDate: 07:00 Monday, 03 June 2019 Timezone:-0700\nMin temperature: 15.0 C\nMax temperature: 22.6 C\nDescription: Low clouds followed by sunshine\nRain probability: 3 %\nWind speed: 9.3 km\/h\n--------------------------------------------------\nDate: 07:00 Tuesday, 04 June 2019 Timezone:-0700\nMin temperature: 15.6 C\nMax temperature: 23.6 C\nDescription: Low clouds followed by sunshine\nRain probability: 0 %\nWind speed: 9.3 km\/h<\/pre>\n\n\n\n
    <\/div>\n\n\n\n

    What have we learnt in this post?\n\n<\/h3>\n\n\n\n
    1. Development of weather forecast program using AccuWeather API<\/li>
    2. Usage of TinyDB<\/li>
    3. Apply quality assurance to make good our products<\/li><\/ol>\n\n\n\n

      (the complete source can be found at GitHub<\/strong>:  https:\/\/github.com\/codeastar\/ez_accuweather_python<\/a> )<\/p>\n","protected":false},"excerpt":{"rendered":"

      We have talked different topics in CodeAStar here, ranging from AWS, CNN, Docker, LGB, Raspberry Pi, RNN and the list goes on. Do you know what is the most popular page here? According to the figure from Google Analytics, and out of my expectation, the most popular page is “Easy Weather Forecast Tool in Python“. […]<\/p>\n","protected":false},"author":1,"featured_media":2019,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"site-sidebar-layout":"default","site-content-layout":"default","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_newsletter_tier_id":0,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[2],"tags":[147,119,150,149,33,148,45,32],"jetpack_publicize_connections":[],"yoast_head":"\nEasy AccuWeather Forecast in Python ⋆ Code A Star<\/title>\n<meta name=\"description\" content=\"Another easy python weather forecast program again. Our weather API to use this time, will be one of the most accurate weather forecasts --- AccuWeather.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Easy AccuWeather Forecast in Python ⋆ Code A Star\" \/>\n<meta property=\"og:description\" content=\"Another easy python weather forecast program again. Our weather API to use this time, will be one of the most accurate weather forecasts --- AccuWeather.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/\" \/>\n<meta property=\"og:site_name\" content=\"Code A Star\" \/>\n<meta property=\"article:publisher\" content=\"codeastar\" \/>\n<meta property=\"article:author\" content=\"codeastar\" \/>\n<meta property=\"article:published_time\" content=\"2019-05-31T18:32:43+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-12-28T05:47:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.codeastar.com\/wp-content\/uploads\/2019\/05\/accuw2.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"419\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Raven Hon\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@codeastar\" \/>\n<meta name=\"twitter:site\" content=\"@codeastar\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Raven Hon\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"11 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/\"},\"author\":{\"name\":\"Raven Hon\",\"@id\":\"https:\/\/www.codeastar.com\/#\/schema\/person\/832d202eb92a3d430097e88c6d0550bd\"},\"headline\":\"Easy AccuWeather Forecast in Python\",\"datePublished\":\"2019-05-31T18:32:43+00:00\",\"dateModified\":\"2019-12-28T05:47:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/\"},\"wordCount\":1241,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/www.codeastar.com\/#\/schema\/person\/832d202eb92a3d430097e88c6d0550bd\"},\"keywords\":[\"AccuWeather\",\"easy\",\"qa\",\"quality assurance\",\"SDLC\",\"TinyDB\",\"tutorial\",\"weather forecast\"],\"articleSection\":[\"We code therefore we are\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/\",\"url\":\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/\",\"name\":\"Easy AccuWeather Forecast in Python ⋆ Code A Star\",\"isPartOf\":{\"@id\":\"https:\/\/www.codeastar.com\/#website\"},\"datePublished\":\"2019-05-31T18:32:43+00:00\",\"dateModified\":\"2019-12-28T05:47:12+00:00\",\"description\":\"Another easy python weather forecast program again. Our weather API to use this time, will be one of the most accurate weather forecasts --- AccuWeather.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.codeastar.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Easy AccuWeather Forecast in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.codeastar.com\/#website\",\"url\":\"https:\/\/www.codeastar.com\/\",\"name\":\"Code A Star\",\"description\":\"We don't wish upon a star, we code a star\",\"publisher\":{\"@id\":\"https:\/\/www.codeastar.com\/#\/schema\/person\/832d202eb92a3d430097e88c6d0550bd\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.codeastar.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.codeastar.com\/#\/schema\/person\/832d202eb92a3d430097e88c6d0550bd\",\"name\":\"Raven Hon\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.codeastar.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/08\/logo70.png?fit=70%2C70&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/08\/logo70.png?fit=70%2C70&ssl=1\",\"width\":70,\"height\":70,\"caption\":\"Raven Hon\"},\"logo\":{\"@id\":\"https:\/\/www.codeastar.com\/#\/schema\/person\/image\/\"},\"description\":\"Raven Hon is\u00a0a 20 years+ veteran in information technology industry who has worked on various projects from console, web, game, banking and mobile applications in different sized companies.\",\"sameAs\":[\"https:\/\/www.codeastar.com\",\"codeastar\",\"https:\/\/twitter.com\/codeastar\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Easy AccuWeather Forecast in Python ⋆ Code A Star","description":"Another easy python weather forecast program again. Our weather API to use this time, will be one of the most accurate weather forecasts --- AccuWeather.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/","og_locale":"en_US","og_type":"article","og_title":"Easy AccuWeather Forecast in Python ⋆ Code A Star","og_description":"Another easy python weather forecast program again. Our weather API to use this time, will be one of the most accurate weather forecasts --- AccuWeather.","og_url":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/","og_site_name":"Code A Star","article_publisher":"codeastar","article_author":"codeastar","article_published_time":"2019-05-31T18:32:43+00:00","article_modified_time":"2019-12-28T05:47:12+00:00","og_image":[{"width":1024,"height":419,"url":"https:\/\/www.codeastar.com\/wp-content\/uploads\/2019\/05\/accuw2.png","type":"image\/png"}],"author":"Raven Hon","twitter_card":"summary_large_image","twitter_creator":"@codeastar","twitter_site":"@codeastar","twitter_misc":{"Written by":"Raven Hon","Est. reading time":"11 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/#article","isPartOf":{"@id":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/"},"author":{"name":"Raven Hon","@id":"https:\/\/www.codeastar.com\/#\/schema\/person\/832d202eb92a3d430097e88c6d0550bd"},"headline":"Easy AccuWeather Forecast in Python","datePublished":"2019-05-31T18:32:43+00:00","dateModified":"2019-12-28T05:47:12+00:00","mainEntityOfPage":{"@id":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/"},"wordCount":1241,"commentCount":2,"publisher":{"@id":"https:\/\/www.codeastar.com\/#\/schema\/person\/832d202eb92a3d430097e88c6d0550bd"},"keywords":["AccuWeather","easy","qa","quality assurance","SDLC","TinyDB","tutorial","weather forecast"],"articleSection":["We code therefore we are"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/","url":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/","name":"Easy AccuWeather Forecast in Python ⋆ Code A Star","isPartOf":{"@id":"https:\/\/www.codeastar.com\/#website"},"datePublished":"2019-05-31T18:32:43+00:00","dateModified":"2019-12-28T05:47:12+00:00","description":"Another easy python weather forecast program again. Our weather API to use this time, will be one of the most accurate weather forecasts --- AccuWeather.","breadcrumb":{"@id":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.codeastar.com\/easy-accuweather-forecast-in-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.codeastar.com\/"},{"@type":"ListItem","position":2,"name":"Easy AccuWeather Forecast in Python"}]},{"@type":"WebSite","@id":"https:\/\/www.codeastar.com\/#website","url":"https:\/\/www.codeastar.com\/","name":"Code A Star","description":"We don't wish upon a star, we code a star","publisher":{"@id":"https:\/\/www.codeastar.com\/#\/schema\/person\/832d202eb92a3d430097e88c6d0550bd"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.codeastar.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.codeastar.com\/#\/schema\/person\/832d202eb92a3d430097e88c6d0550bd","name":"Raven Hon","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.codeastar.com\/#\/schema\/person\/image\/","url":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/08\/logo70.png?fit=70%2C70&ssl=1","contentUrl":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/08\/logo70.png?fit=70%2C70&ssl=1","width":70,"height":70,"caption":"Raven Hon"},"logo":{"@id":"https:\/\/www.codeastar.com\/#\/schema\/person\/image\/"},"description":"Raven Hon is\u00a0a 20 years+ veteran in information technology industry who has worked on various projects from console, web, game, banking and mobile applications in different sized companies.","sameAs":["https:\/\/www.codeastar.com","codeastar","https:\/\/twitter.com\/codeastar"]}]}},"jetpack_featured_media_url":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2019\/05\/accuw2.png?fit=1024%2C419&ssl=1","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8PcRO-w4","jetpack-related-posts":[{"id":387,"url":"https:\/\/www.codeastar.com\/easy-python-weather-forecast-tool\/","url_meta":{"origin":1988,"position":0},"title":"Easy Weather Forecast Tool in Python","author":"Raven Hon","date":"August 4, 2017","format":false,"excerpt":"Since I am going to have a 5-day trip to Sapporo, Hokkaido, Japan at the end of August, I would like to have a weather forecast for my trip. \"So why don't you check from a weather forecast site for free?\" Yes, but I would like to get the exact\u2026","rel":"","context":"In "We code therefore we are"","block_context":{"text":"We code therefore we are","link":"https:\/\/www.codeastar.com\/category\/we-code-therefore-we-are\/"},"img":{"alt_text":"Weather forecast in Python is easy and relaxing","src":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2017\/08\/egg_holidays.png?fit=769%2C655&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2017\/08\/egg_holidays.png?fit=769%2C655&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2017\/08\/egg_holidays.png?fit=769%2C655&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2017\/08\/egg_holidays.png?fit=769%2C655&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":854,"url":"https:\/\/www.codeastar.com\/flask-easy-web-app-python\/","url_meta":{"origin":1988,"position":1},"title":"Easy Weather Forecast Flask Web App with Python","author":"Raven Hon","date":"March 10, 2018","format":false,"excerpt":"We have tried to code an Easy Weather Forecast Tool with Python. Yes, it is fast and easy, but it is just not that convenient to run anything on a command prompt. It is so.... 80s. It would be better if we can make a single-page Flask web app. Then\u2026","rel":"","context":"In "We code therefore we are"","block_context":{"text":"We code therefore we are","link":"https:\/\/www.codeastar.com\/category\/we-code-therefore-we-are\/"},"img":{"alt_text":"EZ Weather Forecast Web App in Flask","src":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/03\/ezw_wep_app.png?fit=1030%2C460&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/03\/ezw_wep_app.png?fit=1030%2C460&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/03\/ezw_wep_app.png?fit=1030%2C460&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/03\/ezw_wep_app.png?fit=1030%2C460&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":968,"url":"https:\/\/www.codeastar.com\/deploy-flask-app-docker-raspberry-pi\/","url_meta":{"origin":1988,"position":2},"title":"Tutorial: Deploy a Flask app with Docker on Raspberry Pi","author":"Raven Hon","date":"April 14, 2018","format":false,"excerpt":"We have just\u00a0installed Docker on our Raspberry Pi, now it is time to bring into action. Do you remember the EZW, Easy Weather Forecast Flask app? Yes, we are going to deploy this EZW flask app. Of course, we do it in the Docker way! Prerequisites Docker installed on a\u2026","rel":"","context":"In "Have a pie, Raspberry Pi(e)"","block_context":{"text":"Have a pie, Raspberry Pi(e)","link":"https:\/\/www.codeastar.com\/category\/have-a-raspberry-pie\/"},"img":{"alt_text":"Deploy Flask app on Raspberry Pi using Docker","src":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/04\/flask_doc.png?fit=1032%2C456&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/04\/flask_doc.png?fit=1032%2C456&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/04\/flask_doc.png?fit=1032%2C456&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2018\/04\/flask_doc.png?fit=1032%2C456&ssl=1&resize=700%2C400 2x"},"classes":[]},{"id":46,"url":"https:\/\/www.codeastar.com\/become-a-coder-in-10-seconds\/","url_meta":{"origin":1988,"position":3},"title":"[Hands-on] Become a coder in 10 seconds!","author":"Raven Hon","date":"June 1, 2017","format":false,"excerpt":"Yes, it is a catchy title, but it still sounds legit. Last time, we talked the talk on the code we pick to code\u00a0--- the Python language.\u00a0Now, let's walk the walk and make no joke --- the hands-on workshop. First things first, install the Python into your machine. No matter\u2026","rel":"","context":"In "We code therefore we are"","block_context":{"text":"We code therefore we are","link":"https:\/\/www.codeastar.com\/category\/we-code-therefore-we-are\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2017\/06\/10s_coder.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2017\/06\/10s_coder.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2017\/06\/10s_coder.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2017\/06\/10s_coder.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":22,"url":"https:\/\/www.codeastar.com\/our-code-to-code-in-2017\/","url_meta":{"origin":1988,"position":4},"title":"[2017] Let’s pick the code to code in 2017","author":"Raven Hon","date":"May 30, 2017","format":false,"excerpt":"There are many programming languages to code, as long as you pick the one you love to code, you will make a great product. I pick our \"lovable\" programming language under three criteria: Popularity Ease of Learning Ease of Use Popularity It is important to find a popular language to\u2026","rel":"","context":"In "We code therefore we are"","block_context":{"text":"We code therefore we are","link":"https:\/\/www.codeastar.com\/category\/we-code-therefore-we-are\/"},"img":{"alt_text":"How do you pick your programming language in 2017?","src":"https:\/\/i0.wp.com\/codeastar.com\/wp-content\/uploads\/2017\/05\/code_2017-1024x249.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/codeastar.com\/wp-content\/uploads\/2017\/05\/code_2017-1024x249.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/codeastar.com\/wp-content\/uploads\/2017\/05\/code_2017-1024x249.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/codeastar.com\/wp-content\/uploads\/2017\/05\/code_2017-1024x249.png?resize=700%2C400 2x"},"classes":[]},{"id":1740,"url":"https:\/\/www.codeastar.com\/flask-backend-react-frontend-weather-1\/","url_meta":{"origin":1988,"position":5},"title":"Flask Backend and React Frontend for Weather Forecast – Part 1","author":"Raven Hon","date":"February 25, 2019","format":false,"excerpt":"We built a weather forecast web app with Flask in past. That was an old fashioned way which we handled all frontend and backend stuff under Flask framework. The best practice for web applications nowadays is separating frontend and backend into 2 modules. So we can utilize both modules to\u2026","rel":"","context":"In "We code therefore we are"","block_context":{"text":"We code therefore we are","link":"https:\/\/www.codeastar.com\/category\/we-code-therefore-we-are\/"},"img":{"alt_text":"Flask backend","src":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2019\/02\/wq_milktea.png?fit=1000%2C500&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2019\/02\/wq_milktea.png?fit=1000%2C500&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2019\/02\/wq_milktea.png?fit=1000%2C500&ssl=1&resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.codeastar.com\/wp-content\/uploads\/2019\/02\/wq_milktea.png?fit=1000%2C500&ssl=1&resize=700%2C400 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/posts\/1988"}],"collection":[{"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/comments?post=1988"}],"version-history":[{"count":34,"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/posts\/1988\/revisions"}],"predecessor-version":[{"id":2189,"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/posts\/1988\/revisions\/2189"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/media\/2019"}],"wp:attachment":[{"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/media?parent=1988"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/categories?post=1988"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codeastar.com\/wp-json\/wp\/v2\/tags?post=1988"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}