Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import argparse
- import requests
- from retrying import retry
- import pandas as pd
- import contextlib
- import warnings
- from functools import partialmethod
- from copy import deepcopy
- TIMEOUT = 60
- MVRP_LOG_URLS = [
- 'https://courier.common.yandex.ru/vrs/api/v1/log/{}/{}',
- 'https://routing-solver-dev.common.yandex.net/api/v1/log/{}/{}'
- ]
- @contextlib.contextmanager
- def no_ssl_verification():
- old_request = requests.Session.request
- requests.Session.request = partialmethod(old_request, verify=False)
- warnings.filterwarnings('ignore', 'Unverified HTTPS request')
- warnings.filterwarnings('ignore', category=ResourceWarning, message='unclosed*<ssl.SSLSocket.*>')
- warnings.simplefilter('ignore', ResourceWarning)
- yield
- warnings.resetwarnings()
- requests.Session.request = old_request
- @retry(retry_on_exception=lambda x: isinstance(x, (requests.exceptions.Timeout,
- requests.exceptions.ConnectionError)),
- stop_max_attempt_number=3
- )
- def get_json_by_mvrp_id(req_resp, solution_id):
- r = None
- for url in MVRP_LOG_URLS:
- with no_ssl_verification():
- r = requests.get(
- url.format(req_resp, solution_id),
- timeout=TIMEOUT,
- verify=False
- )
- if r.status_code == requests.codes.ok:
- break
- else:
- continue
- if r.status_code != 200:
- print('Bad response from MVRP API {} {}'.format(r.status_code, r.text))
- r.raise_for_status()
- return r.json()
- def get_mvrp_solution(solution_id):
- return get_json_by_mvrp_id('response', solution_id)['result']
- def get_mvrp_request(solution_id):
- return get_json_by_mvrp_id('request', solution_id)
- def parse_request(request):
- optional_location_params = [
- 'ref', 'hard_window', 'type', 'shared_service_duration_s', 'delivery_to', 'service_duration_s',
- 'depot_duration_s'
- ]
- orders = []
- for l in request['locations']:
- order = {
- 'point.lat': l['point']['lat'],
- 'point.lon': l['point']['lon'],
- 'time_window': l['time_window']
- }
- for param in optional_location_params:
- if param in l:
- order[param] = l[param]
- for param in ('load_types', 'required_tags'):
- if param in l:
- order[param] = ','.join(l[param])
- if 'shipment_size' in l:
- for param in ('units', 'weight_kg'):
- if param in l['shipment_size']:
- order['shipment_size.' + param] = l['shipment_size'][param]
- if 'volume' in l['shipment_size']:
- for param in ('width_m', 'depth_m', 'height_m'):
- order['shipment_size.volume.' + param] = l['shipment_size']['volume'][param]
- if 'penalty' in l:
- if 'drop' in l['penalty']:
- order['penalty.drop'] = l['penalty']['drop']
- if 'out_of_time' in l['penalty']:
- if 'minute' in l['penalty']['out_of_time']:
- order['penalty.out_of_time.minute'] = l['penalty']['out_of_time']['minute']
- if 'fixed' in l['penalty']['out_of_time']:
- order['penalty.out_of_time.fixed'] = l['penalty']['out_of_time']['fixed']
- orders.append(order)
- optional_depot_params = [
- 'ref', 'hard_window', 'finish_service_duration_s', 'service_duration_s', 'flexible_start_time'
- ]
- d = request['depot']
- depot = {
- 'point.lat': d['point']['lat'],
- 'point.lon': d['point']['lon'],
- 'time_window': d['time_window']
- }
- for param in optional_depot_params:
- if param in d:
- depot[param] = d[param]
- if 'penalty' in d:
- if 'out_of_time' in d['penalty']:
- for param in ('minute', 'fixed'):
- if param in d['penalty']['out_of_time']:
- depot['penalty.out_of_time.' + param] = d['penalty']['out_of_time'][param]
- if 'throughput' in d['penalty']:
- for param in ('fixed', 'kg', 'unit'):
- if param in d['penalty']['throughput']:
- depot['penalty.throughput.' + param] = d['penalty']['throughput'][param]
- if 'throughput' in d:
- for param in ('kg_per_hour', 'units_per_hour'):
- if param in d['throughput']:
- depot['throughput.' + param] = d['throughput'][param]
- optional_vehicle_params = [
- 'return_to_depot', 'max_runs', 'priority', 'travel_time_multiplier', 'company_name', 'ref'
- ]
- vehicles = []
- for v in request.get('vehicles') or [request['vehicle']]:
- vehicle = {}
- for param in optional_vehicle_params:
- if param in v:
- vehicle[param] = v[param]
- if 'tags' in v:
- vehicle['tags'] = ','.join(v['tags'])
- if 'excluded_tags' in v:
- vehicle['excluded_tags'] = ','.join(v['excluded_tags'])
- if 'capacity' in v:
- for param in ('units', 'weight_kg'):
- if param in v['capacity']:
- vehicle['capacity.' + param] = v['capacity'][param]
- if 'volume' in v['capacity']:
- for param in ('width_m', 'depth_m', 'height_m'):
- vehicle['capacity.volume.' + param] = v['capacity']['volume'][param]
- if 'limits' in v['capacity']:
- for param in ('weight_perc', 'units_perc', 'volume_perc'):
- if param in v['capacity']['limits']:
- vehicle['capacity.limits.' + param] = v['capacity']['limits'][param]
- if 'cost' in v:
- for param in ('fixed', 'km', 'hour', 'location', 'run'):
- if param in v['cost']:
- vehicle['cost.' + param] = v['cost'][param]
- if 'shifts' in v:
- for i, shift in enumerate(v['shifts']):
- for param in ('time_window', 'service_duration_s', 'hard_window', 'max_duration_s'):
- if param in shift:
- vehicle['shifts.{}.{}'.format(i, param)] = shift[param]
- if 'penalty' in shift:
- if 'out_of_time' in shift['penalty']:
- for param in ('fixed', 'minute'):
- if param in shift['penalty']['out_of_time']:
- vehicle['shifts.{}.penalty.out_of_time.{}'.format(i, param)] = \
- shift['penalty']['out_of_time'][param]
- vehicles.append(vehicle)
- optional_options_params = [
- 'time_zone', 'thread_count', 'minimize_lateness_risk', 'quality', 'routing_mode', 'weighted_drop_penalty',
- 'temperature', 'critical_lateness_risk_probability', 'eta_model_sigma', 'proximity_factor', 'absolute_time',
- 'default_speed_km_h', 'rand_seed', 'task_count', 'date', 'restart_on_drop', 'merge_multiorders',
- 'solver_time_limit_s', 'minimize', 'matrix_router'
- ]
- options = {}
- for param in optional_options_params:
- if param in request['options']:
- options[param] = request['options'][param]
- # todo: incompatible load types & visited locations
- # todo: recursive parsing
- return orders, vehicles, depot, options
- def save2xlsx(orders, vehicles, depot, options, f_name):
- writer = pd.ExcelWriter(f_name)
- pd.DataFrame(orders).to_excel(writer, 'Orders')
- pd.DataFrame(vehicles).to_excel(writer, 'Vehicles')
- pd.DataFrame([depot]).to_excel(writer, 'Depot')
- pd.DataFrame([options]).to_excel(writer, 'Options')
- writer.save()
- def parse_args():
- parser = argparse.ArgumentParser()
- parser.add_argument('-t', '--task-id', required=True, help='Solver task ID')
- parser.add_argument('-o', '--output', help='Output .xlsx file name')
- return parser.parse_args()
- def main():
- args = parse_args()
- request = get_mvrp_request(args.task_id)
- f_name = args.output or '{}.xlsx'.format(args.task_id)
- save2xlsx(*parse_request(request), f_name=args.output or '{}.xlsx'.format(args.task_id))
- print('Request was saved to file {}'.format(f_name))
- if __name__ == '__main__':
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement