docs: def from_json(cls, data):
          """ Create EPW from json dictionary.
  
              Args:
                  data: {
                  "location": {} , // ladybug location schema
                  "data_collections": [], // list of hourly annual hourly data collection
                      schemas for each of the 35 fields within the EPW file.
                  "metadata": {},  // dict of metadata assigned to all data collections
                  "heating_dict": {}, // dict containing heating design conditions
                  "cooling_dict": {}, // dict containing cooling design conditions
                  "extremes_dict": {}, // dict containing extreme design conditions
                  "extreme_hot_weeks": {}, // dict with values of week-long ladybug
                      analysis period schemas signifying extreme hot weeks.
                  "extreme_cold_weeks": {}, // dict with values of week-long ladybug
                      analysis period schemas signifying extreme cold weeks.
                  "typical_weeks": {}, // dict with values of week-long ladybug
                      analysis period schemas signifying typical weeks.
                  "monthly_ground_temps": {}, // dict with keys as floats signifying
                      depths in meters below ground and values of monthly collection schema
                  "is_ip": Boolean // denote whether the data is in IP units
                  "is_leap_year": Boolean, // denote whether data is for a leap year
                  "daylight_savings_start": 0, // signify when daylight savings starts
                      or 0 for no daylight savings
                  "daylight_savings_end" 0, // signify when daylight savings ends
                      or 0 for no daylight savings
                  "comments_1": String, // epw comments
                  "comments_2": String // epw comments
              }
          """
          # Initialize the class with all data missing
          epw_obj = cls(None)
          epw_obj._is_header_loaded = True
          epw_obj._is_data_loaded = True
  
          # Check required and optional keys
          required_keys = ('location', 'data_collections')
          option_keys_dict = ('metadata', 'heating_dict', 'cooling_dict',
                              'extremes_dict', 'extreme_hot_weeks', 'extreme_cold_weeks',
                              'typical_weeks', 'monthly_ground_temps')
          for key in required_keys:
              assert key in data, 'Required key "{}" is missing!'.format(key)
          assert len(data['data_collections']) == epw_obj._num_of_fields, \
              'The number of data_collections must be {}. Got {}.'.format(
                  epw_obj._num_of_fields, len(data['data_collections']))
          for key in option_keys_dict:
              if key not in data:
                  data[key] = {}
  
          # Set the required properties of the EPW object.
          epw_obj._location = Location.from_json(data['location'])
          epw_obj._data = [HourlyContinuousCollection.from_json(dc)
                           for dc in data['data_collections']]
          if 'is_leap_year' in data:
              epw_obj._is_leap_year = data['is_leap_year']
          if 'is_ip' in data:
              epw_obj._is_ip = data['is_ip']
  
          # Check that the required properties all make sense.
          for dc in epw_obj._data:
              assert isinstance(dc, HourlyContinuousCollection), 'data_collections must ' \
                  'be of HourlyContinuousCollection schema. Got {}'.format(type(dc))
              assert dc.header.analysis_period.is_annual, 'data_collections ' \
                  'analysis_period must be annual.'
              assert dc.header.analysis_period.is_leap_year == epw_obj._is_leap_year, \
                  'data_collections is_leap_year is not aligned with that of the EPW.'
  
          # Set all of the header properties if they exist in the dictionary.
          epw_obj._metadata = data['metadata']
          epw_obj.heating_design_condition_dictionary = data['heating_dict']
          epw_obj.cooling_design_condition_dictionary = data['cooling_dict']
          epw_obj.extreme_design_condition_dictionary = data['extremes_dict']
  
          def _dejson(parent_dict, obj):
              new_dict = {}
              for key, val in parent_dict.items():
                  new_dict[key] = obj.from_json(val)
              return new_dict
          epw_obj.extreme_hot_weeks = _dejson(data['extreme_hot_weeks'], AnalysisPeriod)
          epw_obj.extreme_cold_weeks = _dejson(data['extreme_cold_weeks'], AnalysisPeriod)
          epw_obj.typical_weeks = _dejson(data['typical_weeks'], AnalysisPeriod)
          epw_obj.monthly_ground_temperature = _dejson(
              data['monthly_ground_temps'], MonthlyCollection)
  
          if 'daylight_savings_start' in data:
              epw_obj.daylight_savings_start = data['daylight_savings_start']
          if 'daylight_savings_end' in data:
              epw_obj.daylight_savings_end = data['daylight_savings_end']
          if 'comments_1' in data:
              epw_obj.comments_1 = data['comments_1']
          if 'comments_2' in data:
              epw_obj.comments_2 = data['comments_2']
  
          return epw_obj