Задание:
Привет! Нужно выполнить простой сервис. Я прикрепил два XML – это ответы на поисковые запросы, сделанные к одному из наших партнёров. В ответах лежат варианты перелётов (тег `Flights`) со всей необходимой информацией, чтобы отобразить билет на Aviasales. На основе этих данных, нужно сделать вебсервис, в котором есть эндпоинты, отвечающие на следующие запросы:
* Какие варианты перелёта из DXB в BKK мы получили?
* Самый дорогой/дешёвый, быстрый/долгий и оптимальный варианты
* В чём отличия между результатами двух запросов (изменение маршрутов/условий)?
Язык реализации: `Go` Формат ответа: `json`
По возможности использовать стандартную библиотеку. Язык реализации: `python3` Формат ответа: `json` Используемые библиотеки и инструменты — всё на твой выбор.
Решение:
План действий:
1. Загрузка и разбор XML-файлов с помощью xml.etree.ElementTree.
2. Извлечение информации о рейсах и ценах в словари/списки Python.
3. Реализовать функции для:
- Найти рейсы из DXB в BKK.
- Найти самые дорогие, самые дешевые, самые быстрые, самые длинные
и оптимальные рейсы.
- Сравнить варианты перелетов из двух XML-файлов.
4. Создайте веб-сервис Flask.
5. Определить необходимые конечные точки и связать их с
соответствующими функциями.
6. Возвращать ответы в формате JSON.
Реализация:
Язык Python
import xml.etree.ElementTree as ET
from flask import Flask, jsonify, request
import os
app = Flask(__name__)
def parse_flights(xml_file):
tree = ET.parse(xml_file)
root = tree.getroot()
flights = []
for priced_itinerary in root.findall('.//Flights'):
for flight in priced_itinerary.findall('.//Flight'):
flight_info = {
'Carrier': flight.find('Carrier').text,
'FlightNumber': flight.find('FlightNumber').text,
'Source': flight.find('Source').text,
'Destination': flight.find('Destination').text,
'DepartureTimeStamp': flight.find('DepartureTimeStamp').text,
'ArrivalTimeStamp': flight.find('ArrivalTimeStamp').text,
'Class': flight.find('Class').text,
'NumberOfStops': int(flight.find('NumberOfStops').text),
'FareBasis': flight.find('FareBasis').text.strip(),
'TicketType': flight.find('TicketType').text,
}
flights.append(flight_info)
return flights
def load_data():
data = {}
for file_name in ['RS_ViaOW.xml', 'RS_Via-3.xml']:
data[file_name] = parse_flights(os.path.join('/mnt/data', file_name))
return data
data = load_data()
@app.route('/flights', methods=['GET'])
def get_flights():
flights = [flight for flight in data['RS_ViaOW.xml'] if flight['Source'] == 'DXB' and flight['Destination'] == 'BKK']
return jsonify(flights)
@app.route('/flight-options', methods=['GET'])
def get_flight_options():
flights = [flight for flight in data['RS_ViaOW.xml'] if flight['Source'] == 'DXB' and flight['Destination'] == 'BKK']
if not flights:
return jsonify({"error": "No flights found"}), 404
def get_price(flight):
return float(flight['FareBasis'].split('$')[1].split('_')[0])
def get_duration(flight):
from datetime import datetime
fmt = '%Y-%m-%dT%H%M'
dep = datetime.strptime(flight['DepartureTimeStamp'], fmt)
arr = datetime.strptime(flight['ArrivalTimeStamp'], fmt)
return (arr - dep).total_seconds()
cheapest = min(flights, key=get_price)
most_expensive = max(flights, key=get_price)
fastest = min(flights, key=get_duration)
longest = max(flights, key=get_duration)
optimal = min(flights, key=lambda x: get_price(x) / get_duration(x))
return jsonify({
"cheapest": cheapest,
"most_expensive": most_expensive,
"fastest": fastest,
"longest": longest,
"optimal": optimal
})
@app.route('/compare-flights', methods=['GET'])
def compare_flights():
flights_1 = set(flight['FlightNumber'] for flight in data['RS_ViaOW.xml'])
flights_2 = set(flight['FlightNumber'] for flight in data['RS_Via-3.xml'])
added = flights_2 - flights_1
removed = flights_1 - flights_2
common = flights_1 & flights_2
return jsonify({
"added": list(added),
"removed": list(removed),
"common": list(common)
})
if __name__ == '__main__':
app.run(debug=True)
Следующие шаги
a. Добавьте модульные тесты для конечных точек.
b. Оптимизация разбора XML для больших наборов данных.