python - Defensive conditions when JSON field is missing in API -
i developing small python script in order weather data forecast.io once json document, call class in order create new record saved in database. problem fields (which attributes in class) not informed in api must include kind of defensive code or script break when field not found.
i've found answer of @alex martelli seams pretty good: reading python dict if key might not present
if want different using default value (say, skip printing when key absent), need bit more structure, i.e., either:
for r in results: if 'key_name' in r: print r['key_name']
or
for r in results: try: print r['key_name'] except keyerror: pass
but wondering if must include "if" or "try" on every field want save or there prettier way this? (i want save 27 fields , 27 "if" seems ugly)
this code have far:
from datetime import datetime import tornado.web import tornado.httpclient tornado import gen src.db.city import list_cities src.db.weather import weather motorengine import * @gen.coroutine def forecastio_api(): http_client = tornado.httpclient.asynchttpclient() base_url = "https://api.forecast.io/forecast/apikey" city yield list_cities() city in city: url = base_url + "/%s,%s" %(str(city.loc[0]), str(city.loc[1])) response = yield http_client.fetch(url) json = tornado.escape.json_decode(response.body) day in json['daily']['data']: weather = weather(city=city, time = datetime.fromtimestamp(day['time']), summary = day.get('summary'), icon = day.get('icon'), sunrise_time = datetime.fromtimestamp(day.get('sunrisetime')), sunset_time = datetime.fromtimestamp(day.get('sunsettime')), moon_phase = day.get('moonphase'), precip_intensity = day.get('precipintensity'), precip_intensity_max = day.get('precipintensitymax'), precip_intensity_max_time = datetime.fromtimestamp(day.get('precipintensitymaxtime')), precip_probability = day.get('precipprobability'), precip_type = day.get('preciptype'), temperature_min = day.get('temperaturemin'), temperature_min_time = datetime.fromtimestamp(day.get('temperaturemintime')), temperature_max = day.get('temperaturemax'), temperature_max_time = datetime.fromtimestamp(day.get('temperaturemaxtime')), apparent_temperature_min = day.get('apparenttemperaturemin'), apparent_temperature_min_time = datetime.fromtimestamp(day.get('apparenttemperaturemintime')), apparent_temperature_max = day.get('apparenttemperaturemax'), apparent_temperature_max_time = datetime.fromtimestamp(day.get('apparenttemperaturemaxtime')), dew_point = day.get('dewpoint'), humidity = day.get('humidity'), wind_speed = day.get('windspeed'), wind_bearing = day.get('windbearing'), visibility = day.get('visibility'), cloud_cover = day.get('cloudcover'), pressure = day.get('pressure'), ozone = day.get('ozone') ) weather.create() if __name__ == '__main__': io_loop = tornado.ioloop.ioloop.instance() connect("database", host="localhost", port=27017, io_loop=io_loop) forecastio_api() io_loop.start()
and weather class using motornegine:
from tornado import gen motorengine import document motorengine.fields import datetimefield, decimalfield, referencefield, stringfield src.db.city import city class weather(document): __collection__ = 'weather' __lazy__ = false city = referencefield(reference_document_type=city) time = datetimefield(required=true) summary = stringfield() icon = stringfield() sunrise_time = datetimefield() sunset_time = datetimefield() moon_phase = decimalfield(precision=2) precip_intensity = decimalfield(precision=4) precip_intensity_max = decimalfield(precision=4) precip_intensity_max_time = datetimefield() precip_probability = decimalfield(precision=2) precip_type = stringfield() temperature_min = decimalfield(precision=2) temperature_min_time = datetimefield() temperature_max = decimalfield(precision=2) temperature_max_time = datetimefield() apparent_temperature_min = decimalfield(precision=2) apparent_temperature_min_time = datetimefield() apparent_temperature_max = decimalfield(precision=2) apparent_temperature_max_time = datetimefield() dew_point = decimalfield(precision=2) humidity = decimalfield(precision=2) wind_speed = decimalfield(precision=2) wind_bearing = decimalfield(precision=2) visibility = decimalfield(precision=2) cloud_cover = decimalfield(precision=2) pressure = decimalfield(precision=2) ozone = decimalfield(precision=2) create_time = datetimefield(auto_now_on_insert=true) @gen.coroutine def create(self): yield self.save()
you can check schematics. library helps define objects can populated dicts(you can turn json python dict). allows define validation rules on each property. object throw modelvalidationerror
error when properties missing or in wrong format. schematics allows add default values , lot more nice stuff when define models.
Comments
Post a Comment