Script to print weather report from OpenWeatherMap API This script prints the weather (fetching the information from a public API).

If anyone could review my code and answer my question about code structure and how should I code in the right way, I really appreciate that very much.

Questions:


I used many functions to do just one specific things, and return their value to be used in the next functions. Is this right?
In main I used composed way for calling functions, Is this right or there is a better way?


Note: You need to obtain your API key to try it.

import datetime
import json
import urllib.request


def time_converter(time):
    converted_time = datetime.datetime.fromtimestamp(
        int(time)
    ).strftime('%I:%M %p')
    return converted_time


def url_builder(city_id):
    user_api = ''  # Obtain yours form: http://openweathermap.org/
    unit = 'metric'  # For Fahrenheit use imperial, for Celsius use metric, and the default is Kelvin.
    api = 'http://api.openweathermap.org/data/2.5/weather?id='     # Search for your city ID here: http://bulk.openweathermap.org/sample/city.list.json.gz

    full_api_url = api + str(city_id) + '&amp;mode=json&amp;units=' + unit + '&amp;APPID=' + user_api
    return full_api_url


def data_fetch(full_api_url):
    url = urllib.request.urlopen(full_api_url)
    output = url.read().decode('utf-8')
    raw_api_dict = json.loads(output)
    url.close()
    return raw_api_dict


def data_organizer(raw_api_dict):
    data = dict(
        city=raw_api_dict.get('name'),
        country=raw_api_dict.get('sys').get('country'),
        temp=raw_api_dict.get('main').get('temp'),
        temp_max=raw_api_dict.get('main').get('temp_max'),
        temp_min=raw_api_dict.get('main').get('temp_min'),
        humidity=raw_api_dict.get('main').get('humidity'),
        pressure=raw_api_dict.get('main').get('pressure'),
        sky=raw_api_dict['weather'][0]['main'],
        sunrise=time_converter(raw_api_dict.get('sys').get('sunrise')),
        sunset=time_converter(raw_api_dict.get('sys').get('sunset')),
        wind=raw_api_dict.get('wind').get('speed'),
        wind_deg=raw_api_dict.get('deg'),
        dt=time_converter(raw_api_dict.get('dt')),
        cloudiness=raw_api_dict.get('clouds').get('all')
    )
    return data


def data_output(data):
    m_symbol = '\xb0' + 'C'
    print('---------------------------------------')
    print('Current weather in: {}, {}:'.format(data['city'], data['country']))
    print(data['temp'], m_symbol, data['sky'])
    print('Max: {}, Min: {}'.format(data['temp_max'], data['temp_min']))
    print('')
    print('Wind Speed: {}, Degree: {}'.format(data['wind'], data['wind_deg']))
    print('Humidity: {}'.format(data['humidity']))
    print('Cloud: {}'.format(data['cloudiness']))
    print('Pressure: {}'.format(data['pressure']))
    print('Sunrise at: {}'.format(data['sunrise']))
    print('Sunset at: {}'.format(data['sunset']))
    print('')
    print('Last update from the server: {}'.format(data['dt']))
    print('---------------------------------------')


if __name__ == '__main__':
    try:
        data_output(data_organizer(data_fetch(url_builder(2172797))))
    except IOError:
        print('no internet')


Output:




---------------------------------------
Current weather in: Cairns, AU:
14.81 °C Clear
Max: 17, Min: 10.56

Wind Speed: 1.91, Degree: None
Humidity: 100
Cloud: 0
Pressure: 1015
Sunrise at: 11:41 PM
Sunset at: 10:50 AM

Last update from the server: 11:35 PM
---------------------------------------
For your first question, yes, breaking down functions to do really specific things is always good. Makes it easier to use the same functions again in other situations etc. 

For your second question, I would personally only call one function at a time, for me it makes it easier to read and understand.

Also, you can have a single print statement for a multi-line string for example:

print('''' Hello
world
      isn't this cool?'''


and that would print:

Hello
world
      isn't this cool?


but in your circumstance it might be a little bit difficult with all those format().