Commit 591253988601fcc7b3dcaff9bc6c70803f6beec3
1 parent
d5474086
Exists in
master
Improve resilience.
Showing
1 changed file
with
275 additions
and
268 deletions
Show diff stats
flaskr/controllers/main_controller.py
... | ... | @@ -240,318 +240,325 @@ def compute(): # process the queue of estimation requests |
240 | 240 | _estimation.warnings = _warning_message |
241 | 241 | db.session.commit() |
242 | 242 | |
243 | - response = "" | |
243 | + try: | |
244 | + response = "" | |
244 | 245 | |
245 | - count_working = Estimation.query \ | |
246 | - .filter_by(status=StatusEnum.working) \ | |
247 | - .count() | |
246 | + count_working = Estimation.query \ | |
247 | + .filter_by(status=StatusEnum.working) \ | |
248 | + .count() | |
248 | 249 | |
249 | - if 0 < count_working: | |
250 | - return _respond("Already working on estimation.") | |
250 | + if 0 < count_working: | |
251 | + return _respond("Already working on estimation.") | |
251 | 252 | |
252 | - try: | |
253 | - estimation = Estimation.query \ | |
254 | - .filter_by(status=StatusEnum.pending) \ | |
255 | - .order_by(Estimation.id.asc()) \ | |
256 | - .first() | |
257 | - except sqlalchemy.orm.exc.NoResultFound: | |
258 | - return _respond("No estimation in the queue.") | |
259 | - except Exception as e: | |
260 | - return _respond("Database error: %s" % (e,)) | |
253 | + try: | |
254 | + estimation = Estimation.query \ | |
255 | + .filter_by(status=StatusEnum.pending) \ | |
256 | + .order_by(Estimation.id.asc()) \ | |
257 | + .first() | |
258 | + except sqlalchemy.orm.exc.NoResultFound: | |
259 | + return _respond("No estimation in the queue.") | |
260 | + except Exception as e: | |
261 | + return _respond("Database error: %s" % (e,)) | |
262 | + | |
263 | + if not estimation: | |
264 | + return _respond("No estimation in the queue.") | |
265 | + | |
266 | + estimation.status = StatusEnum.working | |
267 | + db.session.commit() | |
261 | 268 | |
262 | - if not estimation: | |
263 | - return _respond("No estimation in the queue.") | |
269 | + response += u"Processing estimation `%s`...\n" % ( | |
270 | + estimation.public_id | |
271 | + ) | |
264 | 272 | |
265 | - estimation.status = StatusEnum.working | |
266 | - db.session.commit() | |
273 | + failed_addresses = [] | |
274 | + geocoder = CachedGeocoder() | |
267 | 275 | |
268 | - response += u"Processing estimation `%s`...\n" % ( | |
269 | - estimation.public_id | |
270 | - ) | |
276 | + # GEOCODE ORIGINS ######################################################### | |
271 | 277 | |
272 | - failed_addresses = [] | |
273 | - geocoder = CachedGeocoder() | |
278 | + origins_addresses = estimation.origin_addresses.strip().split("\n") | |
279 | + origins = [] | |
274 | 280 | |
275 | - # GEOCODE ORIGINS ######################################################### | |
281 | + for i in range(len(origins_addresses)): | |
276 | 282 | |
277 | - origins_addresses = estimation.origin_addresses.strip().split("\n") | |
278 | - origins = [] | |
283 | + origin_address = origins_addresses[i].strip() | |
284 | + if origin_address in failed_addresses: | |
285 | + continue | |
279 | 286 | |
280 | - for i in range(len(origins_addresses)): | |
287 | + try: | |
288 | + origin = geocoder.geocode(origin_address.encode('utf-8')) | |
289 | + except geopy.exc.GeopyError as e: | |
290 | + response += u"Failed to geocode origin `%s`.\n%s\n" % ( | |
291 | + origin_address, e, | |
292 | + ) | |
293 | + _handle_warning(estimation, response) | |
294 | + failed_addresses.append(origin_address) | |
295 | + continue | |
281 | 296 | |
282 | - origin_address = origins_addresses[i].strip() | |
283 | - if origin_address in failed_addresses: | |
284 | - continue | |
297 | + if origin is None: | |
298 | + response += u"Failed to geocode origin `%s`.\n" % ( | |
299 | + origin_address, | |
300 | + ) | |
301 | + _handle_warning(estimation, response) | |
302 | + failed_addresses.append(origin_address) | |
303 | + continue | |
285 | 304 | |
286 | - try: | |
287 | - origin = geocoder.geocode(origin_address.encode('utf-8')) | |
288 | - except geopy.exc.GeopyError as e: | |
289 | - response += u"Failed to geocode origin `%s`.\n%s\n" % ( | |
290 | - origin_address, e, | |
291 | - ) | |
292 | - _handle_warning(estimation, response) | |
293 | - failed_addresses.append(origin_address) | |
294 | - continue | |
305 | + origins.append(origin) | |
295 | 306 | |
296 | - if origin is None: | |
297 | - response += u"Failed to geocode origin `%s`.\n" % ( | |
298 | - origin_address, | |
307 | + response += u"Origin: %s == %s (%f, %f)\n" % ( | |
308 | + origin_address, origin.address, | |
309 | + origin.latitude, origin.longitude, | |
299 | 310 | ) |
300 | - _handle_warning(estimation, response) | |
301 | - failed_addresses.append(origin_address) | |
302 | - continue | |
303 | 311 | |
304 | - origins.append(origin) | |
312 | + # GEOCODE DESTINATIONS #################################################### | |
305 | 313 | |
306 | - response += u"Origin: %s == %s (%f, %f)\n" % ( | |
307 | - origin_address, origin.address, | |
308 | - origin.latitude, origin.longitude, | |
309 | - ) | |
314 | + destinations_addresses = estimation.destination_addresses.strip().split("\n") | |
315 | + destinations = [] | |
310 | 316 | |
311 | - # GEOCODE DESTINATIONS #################################################### | |
317 | + for i in range(len(destinations_addresses)): | |
312 | 318 | |
313 | - destinations_addresses = estimation.destination_addresses.strip().split("\n") | |
314 | - destinations = [] | |
319 | + destination_address = destinations_addresses[i].strip() | |
320 | + if destination_address in failed_addresses: | |
321 | + continue | |
315 | 322 | |
316 | - for i in range(len(destinations_addresses)): | |
323 | + try: | |
324 | + destination = geocoder.geocode(destination_address.encode('utf-8')) | |
325 | + except geopy.exc.GeopyError as e: | |
326 | + response += u"Failed to geocode destination `%s`.\n%s\n" % ( | |
327 | + destination_address, e, | |
328 | + ) | |
329 | + _handle_warning(estimation, response) | |
330 | + failed_addresses.append(destination_address) | |
331 | + continue | |
317 | 332 | |
318 | - destination_address = destinations_addresses[i].strip() | |
319 | - if destination_address in failed_addresses: | |
320 | - continue | |
333 | + if destination is None: | |
334 | + response += u"Failed to geocode destination `%s`.\n" % ( | |
335 | + destination_address, | |
336 | + ) | |
337 | + _handle_warning(estimation, response) | |
338 | + failed_addresses.append(destination_address) | |
339 | + continue | |
321 | 340 | |
322 | - try: | |
323 | - destination = geocoder.geocode(destination_address.encode('utf-8')) | |
324 | - except geopy.exc.GeopyError as e: | |
325 | - response += u"Failed to geocode destination `%s`.\n%s\n" % ( | |
326 | - destination_address, e, | |
327 | - ) | |
328 | - _handle_warning(estimation, response) | |
329 | - failed_addresses.append(destination_address) | |
330 | - continue | |
341 | + # print(repr(destination.raw)) | |
331 | 342 | |
332 | - if destination is None: | |
333 | - response += u"Failed to geocode destination `%s`.\n" % ( | |
334 | - destination_address, | |
343 | + destinations.append(destination) | |
344 | + | |
345 | + response += u"Destination: %s == %s (%f, %f)\n" % ( | |
346 | + destination_address, destination.address, | |
347 | + destination.latitude, destination.longitude, | |
335 | 348 | ) |
336 | - _handle_warning(estimation, response) | |
337 | - failed_addresses.append(destination_address) | |
338 | - continue | |
339 | 349 | |
340 | - # print(repr(destination.raw)) | |
350 | + # GTFO IF NO ORIGINS OR NO DESTINATIONS ################################### | |
341 | 351 | |
342 | - destinations.append(destination) | |
352 | + if 0 == len(origins): | |
353 | + response += u"Failed to geocode all the origin(s).\n" | |
354 | + _handle_failure(estimation, response) | |
355 | + return _respond(response) | |
356 | + if 0 == len(destinations): | |
357 | + response += u"Failed to geocode all the destination(s).\n" | |
358 | + _handle_failure(estimation, response) | |
359 | + return _respond(response) | |
343 | 360 | |
344 | - response += u"Destination: %s == %s (%f, %f)\n" % ( | |
345 | - destination_address, destination.address, | |
346 | - destination.latitude, destination.longitude, | |
347 | - ) | |
361 | + # GRAB AND CONFIGURE THE EMISSION MODELS ################################## | |
348 | 362 | |
349 | - # GTFO IF NO ORIGINS OR NO DESTINATIONS ################################### | |
363 | + emission_models = estimation.get_models() | |
364 | + # print(emission_models) | |
350 | 365 | |
351 | - if 0 == len(origins): | |
352 | - response += u"Failed to geocode all the origin(s).\n" | |
353 | - _handle_failure(estimation, response) | |
354 | - return _respond(response) | |
355 | - if 0 == len(destinations): | |
356 | - response += u"Failed to geocode all the destination(s).\n" | |
357 | - _handle_failure(estimation, response) | |
358 | - return _respond(response) | |
359 | - | |
360 | - # GRAB AND CONFIGURE THE EMISSION MODELS ################################## | |
361 | - | |
362 | - emission_models = estimation.get_models() | |
363 | - # print(emission_models) | |
364 | - | |
365 | - extra_config = { | |
366 | - 'use_train_below_distance': estimation.use_train_below_km, | |
367 | - # 'use_train_below_distance': 300, | |
368 | - } | |
369 | - | |
370 | - # PREPARE RESULT DICTIONARY THAT WILL BE STORED ########################### | |
371 | - | |
372 | - results = {} | |
373 | - | |
374 | - # UTILITY PRIVATE FUNCTION(S) ############################################# | |
375 | - | |
376 | - def get_city_key(_location): | |
377 | - # Will this hack hold? Suspense... | |
378 | - return _location.address.split(',')[0] | |
379 | - | |
380 | - # _city_key = _location.address | |
381 | - # # if 'address100' in _location.raw['address']: | |
382 | - # # _city_key = _location.raw['address']['address100'] | |
383 | - # if 'city' in _location.raw['address']: | |
384 | - # _city_key = _location.raw['address']['city'] | |
385 | - # elif 'state' in _location.raw['address']: | |
386 | - # _city_key = _location.raw['address']['state'] | |
387 | - # return _city_key | |
388 | - | |
389 | - def compute_one_to_many( | |
390 | - _origin, | |
391 | - _destinations, | |
392 | - _extra_config=None | |
393 | - ): | |
394 | - _results = {} | |
395 | - footprints = {} | |
396 | - | |
397 | - destinations_by_city_key = {} | |
398 | - | |
399 | - cities_sum_foot = {} | |
400 | - cities_sum_dist = {} | |
401 | - cities_dict_first_model = None | |
402 | - for model in emission_models: | |
403 | - cities_dict = {} | |
404 | - for _destination in _destinations: | |
405 | - footprint = model.compute_travel_footprint( | |
406 | - origin_latitude=_origin.latitude, | |
407 | - origin_longitude=_origin.longitude, | |
408 | - destination_latitude=_destination.latitude, | |
409 | - destination_longitude=_destination.longitude, | |
410 | - extra_config=_extra_config, | |
411 | - ) | |
366 | + extra_config = { | |
367 | + 'use_train_below_distance': estimation.use_train_below_km, | |
368 | + # 'use_train_below_distance': 300, | |
369 | + } | |
412 | 370 | |
413 | - _key = get_city_key(_destination) | |
414 | - | |
415 | - destinations_by_city_key[_key] = _destination | |
416 | - | |
417 | - if _key not in cities_dict: | |
418 | - cities_dict[_key] = { | |
419 | - 'city': _key, | |
420 | - 'address': _destination.address, | |
421 | - 'footprint': 0.0, | |
422 | - 'distance': 0.0, | |
423 | - 'train_trips': 0, | |
424 | - 'plane_trips': 0, | |
425 | - } | |
426 | - cities_dict[_key]['footprint'] += footprint['co2eq_kg'] | |
427 | - cities_dict[_key]['distance'] += footprint['distance_km'] | |
428 | - cities_dict[_key]['train_trips'] += footprint['train_trips'] | |
429 | - cities_dict[_key]['plane_trips'] += footprint['plane_trips'] | |
430 | - if _key not in cities_sum_foot: | |
431 | - cities_sum_foot[_key] = 0.0 | |
432 | - cities_sum_foot[_key] += footprint['co2eq_kg'] | |
433 | - if _key not in cities_sum_dist: | |
434 | - cities_sum_dist[_key] = 0.0 | |
435 | - cities_sum_dist[_key] += footprint['distance_km'] | |
436 | - | |
437 | - cities = sorted(cities_dict.values(), key=lambda c: c['footprint']) | |
438 | - | |
439 | - footprints[model.slug] = { | |
440 | - 'cities': cities, | |
441 | - } | |
371 | + # PREPARE RESULT DICTIONARY THAT WILL BE STORED ########################### | |
372 | + | |
373 | + results = {} | |
374 | + | |
375 | + # UTILITY PRIVATE FUNCTION(S) ############################################# | |
376 | + | |
377 | + def get_city_key(_location): | |
378 | + # Will this hack hold? Suspense... | |
379 | + return _location.address.split(',')[0] | |
380 | + | |
381 | + # _city_key = _location.address | |
382 | + # # if 'address100' in _location.raw['address']: | |
383 | + # # _city_key = _location.raw['address']['address100'] | |
384 | + # if 'city' in _location.raw['address']: | |
385 | + # _city_key = _location.raw['address']['city'] | |
386 | + # elif 'state' in _location.raw['address']: | |
387 | + # _city_key = _location.raw['address']['state'] | |
388 | + # return _city_key | |
389 | + | |
390 | + def compute_one_to_many( | |
391 | + _origin, | |
392 | + _destinations, | |
393 | + _extra_config=None | |
394 | + ): | |
395 | + _results = {} | |
396 | + footprints = {} | |
397 | + | |
398 | + destinations_by_city_key = {} | |
399 | + | |
400 | + cities_sum_foot = {} | |
401 | + cities_sum_dist = {} | |
402 | + cities_dict_first_model = None | |
403 | + for model in emission_models: | |
404 | + cities_dict = {} | |
405 | + for _destination in _destinations: | |
406 | + footprint = model.compute_travel_footprint( | |
407 | + origin_latitude=_origin.latitude, | |
408 | + origin_longitude=_origin.longitude, | |
409 | + destination_latitude=_destination.latitude, | |
410 | + destination_longitude=_destination.longitude, | |
411 | + extra_config=_extra_config, | |
412 | + ) | |
442 | 413 | |
443 | - if cities_dict_first_model is None: | |
444 | - cities_dict_first_model = deepcopy(cities_dict) | |
445 | - | |
446 | - _results['footprints'] = footprints | |
447 | - | |
448 | - total_foot = 0.0 | |
449 | - total_dist = 0.0 | |
450 | - total_train_trips = 0 | |
451 | - total_plane_trips = 0 | |
452 | - | |
453 | - cities_mean_dict = {} | |
454 | - for city in cities_sum_foot.keys(): | |
455 | - city_mean_foot = 1.0 * cities_sum_foot[city] / len(emission_models) | |
456 | - city_mean_dist = 1.0 * cities_sum_dist[city] / len(emission_models) | |
457 | - city_train_trips = cities_dict_first_model[city]['train_trips'] | |
458 | - city_plane_trips = cities_dict_first_model[city]['plane_trips'] | |
459 | - cities_mean_dict[city] = { | |
460 | - 'address': destinations_by_city_key[city].address, | |
461 | - 'city': city, | |
462 | - 'footprint': city_mean_foot, | |
463 | - 'distance': city_mean_dist, | |
464 | - 'train_trips': city_train_trips, | |
465 | - 'plane_trips': city_plane_trips, | |
414 | + _key = get_city_key(_destination) | |
415 | + | |
416 | + destinations_by_city_key[_key] = _destination | |
417 | + | |
418 | + if _key not in cities_dict: | |
419 | + cities_dict[_key] = { | |
420 | + 'city': _key, | |
421 | + 'address': _destination.address, | |
422 | + 'footprint': 0.0, | |
423 | + 'distance': 0.0, | |
424 | + 'train_trips': 0, | |
425 | + 'plane_trips': 0, | |
426 | + } | |
427 | + cities_dict[_key]['footprint'] += footprint['co2eq_kg'] | |
428 | + cities_dict[_key]['distance'] += footprint['distance_km'] | |
429 | + cities_dict[_key]['train_trips'] += footprint['train_trips'] | |
430 | + cities_dict[_key]['plane_trips'] += footprint['plane_trips'] | |
431 | + if _key not in cities_sum_foot: | |
432 | + cities_sum_foot[_key] = 0.0 | |
433 | + cities_sum_foot[_key] += footprint['co2eq_kg'] | |
434 | + if _key not in cities_sum_dist: | |
435 | + cities_sum_dist[_key] = 0.0 | |
436 | + cities_sum_dist[_key] += footprint['distance_km'] | |
437 | + | |
438 | + cities = sorted(cities_dict.values(), key=lambda c: c['footprint']) | |
439 | + | |
440 | + footprints[model.slug] = { | |
441 | + 'cities': cities, | |
442 | + } | |
443 | + | |
444 | + if cities_dict_first_model is None: | |
445 | + cities_dict_first_model = deepcopy(cities_dict) | |
446 | + | |
447 | + _results['footprints'] = footprints | |
448 | + | |
449 | + total_foot = 0.0 | |
450 | + total_dist = 0.0 | |
451 | + total_train_trips = 0 | |
452 | + total_plane_trips = 0 | |
453 | + | |
454 | + cities_mean_dict = {} | |
455 | + for city in cities_sum_foot.keys(): | |
456 | + city_mean_foot = 1.0 * cities_sum_foot[city] / len(emission_models) | |
457 | + city_mean_dist = 1.0 * cities_sum_dist[city] / len(emission_models) | |
458 | + city_train_trips = cities_dict_first_model[city]['train_trips'] | |
459 | + city_plane_trips = cities_dict_first_model[city]['plane_trips'] | |
460 | + cities_mean_dict[city] = { | |
461 | + 'address': destinations_by_city_key[city].address, | |
462 | + 'city': city, | |
463 | + 'footprint': city_mean_foot, | |
464 | + 'distance': city_mean_dist, | |
465 | + 'train_trips': city_train_trips, | |
466 | + 'plane_trips': city_plane_trips, | |
467 | + } | |
468 | + total_foot += city_mean_foot | |
469 | + total_dist += city_mean_dist | |
470 | + total_train_trips += city_train_trips | |
471 | + total_plane_trips += city_plane_trips | |
472 | + | |
473 | + cities_mean = [cities_mean_dict[k] for k in cities_mean_dict.keys()] | |
474 | + cities_mean = sorted(cities_mean, key=lambda c: c['footprint']) | |
475 | + | |
476 | + _results['mean_footprint'] = { # DEPRECATED? | |
477 | + 'cities': cities_mean | |
466 | 478 | } |
467 | - total_foot += city_mean_foot | |
468 | - total_dist += city_mean_dist | |
469 | - total_train_trips += city_train_trips | |
470 | - total_plane_trips += city_plane_trips | |
479 | + _results['cities'] = cities_mean | |
471 | 480 | |
472 | - cities_mean = [cities_mean_dict[k] for k in cities_mean_dict.keys()] | |
473 | - cities_mean = sorted(cities_mean, key=lambda c: c['footprint']) | |
481 | + _results['total'] = total_foot # DEPRECATED | |
482 | + _results['footprint'] = total_foot | |
474 | 483 | |
475 | - _results['mean_footprint'] = { # DEPRECATED? | |
476 | - 'cities': cities_mean | |
477 | - } | |
478 | - _results['cities'] = cities_mean | |
479 | - | |
480 | - _results['total'] = total_foot # DEPRECATED | |
481 | - _results['footprint'] = total_foot | |
482 | - | |
483 | - _results['distance'] = total_dist | |
484 | - _results['train_trips'] = total_train_trips | |
485 | - _results['plane_trips'] = total_plane_trips | |
486 | - | |
487 | - return _results | |
488 | - | |
489 | - # SCENARIO A : One Origin, At Least One Destination ####################### | |
490 | - # | |
491 | - # In this scenario, we compute the sum of each of the travels' footprint, | |
492 | - # for each of the Emission Models, and present a mean of all Models. | |
493 | - # | |
494 | - if 1 == len(origins): | |
495 | - estimation.scenario = ScenarioEnum.one_to_many | |
496 | - results = compute_one_to_many( | |
497 | - _origin=origins[0], | |
498 | - _destinations=destinations, | |
499 | - _extra_config=extra_config, | |
500 | - ) | |
484 | + _results['distance'] = total_dist | |
485 | + _results['train_trips'] = total_train_trips | |
486 | + _results['plane_trips'] = total_plane_trips | |
501 | 487 | |
502 | - # SCENARIO B : At Least One Origin, One Destination ####################### | |
503 | - # | |
504 | - # Same as A for now. | |
505 | - # | |
506 | - elif 1 == len(destinations): | |
507 | - estimation.scenario = ScenarioEnum.many_to_one | |
508 | - results = compute_one_to_many( | |
509 | - _origin=destinations[0], | |
510 | - _destinations=origins, | |
511 | - _extra_config=extra_config, | |
512 | - ) | |
488 | + return _results | |
513 | 489 | |
514 | - # SCENARIO C : At Least One Origin, At Least One Destination ############## | |
515 | - # | |
516 | - # Run Scenario A for each Destination, and expose optimum Destination. | |
517 | - # | |
518 | - else: | |
519 | - estimation.scenario = ScenarioEnum.many_to_many | |
520 | - unique_city_keys = [] | |
521 | - result_cities = [] | |
522 | - for destination in destinations: | |
523 | - city_key = get_city_key(destination) | |
524 | - | |
525 | - if city_key in unique_city_keys: | |
526 | - continue | |
527 | - else: | |
528 | - unique_city_keys.append(city_key) | |
490 | + # SCENARIO A : One Origin, At Least One Destination ####################### | |
491 | + # | |
492 | + # In this scenario, we compute the sum of each of the travels' footprint, | |
493 | + # for each of the Emission Models, and present a mean of all Models. | |
494 | + # | |
495 | + if 1 == len(origins): | |
496 | + estimation.scenario = ScenarioEnum.one_to_many | |
497 | + results = compute_one_to_many( | |
498 | + _origin=origins[0], | |
499 | + _destinations=destinations, | |
500 | + _extra_config=extra_config, | |
501 | + ) | |
529 | 502 | |
530 | - city_results = compute_one_to_many( | |
531 | - _origin=destination, | |
503 | + # SCENARIO B : At Least One Origin, One Destination ####################### | |
504 | + # | |
505 | + # Same as A for now. | |
506 | + # | |
507 | + elif 1 == len(destinations): | |
508 | + estimation.scenario = ScenarioEnum.many_to_one | |
509 | + results = compute_one_to_many( | |
510 | + _origin=destinations[0], | |
532 | 511 | _destinations=origins, |
533 | 512 | _extra_config=extra_config, |
534 | 513 | ) |
535 | - city_results['city'] = city_key | |
536 | - city_results['address'] = destination.address | |
537 | - result_cities.append(city_results) | |
538 | 514 | |
539 | - result_cities = sorted(result_cities, key=lambda c: int(c['footprint'])) | |
540 | - results = { | |
541 | - 'cities': result_cities, | |
542 | - } | |
515 | + # SCENARIO C : At Least One Origin, At Least One Destination ############## | |
516 | + # | |
517 | + # Run Scenario A for each Destination, and expose optimum Destination. | |
518 | + # | |
519 | + else: | |
520 | + estimation.scenario = ScenarioEnum.many_to_many | |
521 | + unique_city_keys = [] | |
522 | + result_cities = [] | |
523 | + for destination in destinations: | |
524 | + city_key = get_city_key(destination) | |
525 | + | |
526 | + if city_key in unique_city_keys: | |
527 | + continue | |
528 | + else: | |
529 | + unique_city_keys.append(city_key) | |
543 | 530 | |
544 | - # WRITE RESULTS INTO THE DATABASE ######################################### | |
531 | + city_results = compute_one_to_many( | |
532 | + _origin=destination, | |
533 | + _destinations=origins, | |
534 | + _extra_config=extra_config, | |
535 | + ) | |
536 | + city_results['city'] = city_key | |
537 | + city_results['address'] = destination.address | |
538 | + result_cities.append(city_results) | |
539 | + | |
540 | + result_cities = sorted(result_cities, key=lambda c: int(c['footprint'])) | |
541 | + results = { | |
542 | + 'cities': result_cities, | |
543 | + } | |
544 | + | |
545 | + # WRITE RESULTS INTO THE DATABASE ######################################### | |
545 | 546 | |
546 | - estimation.status = StatusEnum.success | |
547 | - estimation.output_yaml = yaml_dump(results) | |
548 | - db.session.commit() | |
547 | + estimation.status = StatusEnum.success | |
548 | + estimation.output_yaml = yaml_dump(results) | |
549 | + db.session.commit() | |
550 | + | |
551 | + # FINALLY, RESPOND ######################################################## | |
549 | 552 | |
550 | - # FINALLY, RESPOND ######################################################## | |
553 | + response += yaml_dump(results) + "\n" | |
551 | 554 | |
552 | - response += yaml_dump(results) + "\n" | |
555 | + return _respond(response) | |
553 | 556 | |
554 | - return _respond(response) | |
557 | + except Exception as e: | |
558 | + errmsg = "Computation failed : %s" % e | |
559 | + if estimation: | |
560 | + _handle_failure(estimation, errmsg) | |
561 | + return _respond(errmsg) | |
555 | 562 | |
556 | 563 | |
557 | 564 | @main.route("/estimation/<public_id>.<extension>") |
... | ... | @@ -563,7 +570,7 @@ def consult_estimation(public_id, extension): |
563 | 570 | except sqlalchemy.orm.exc.NoResultFound: |
564 | 571 | return abort(404) |
565 | 572 | except Exception as e: |
566 | - # TODO: log | |
573 | + # TODO: log? | |
567 | 574 | return abort(500) |
568 | 575 | |
569 | 576 | # allowed_formats = ['html'] | ... | ... |