В папке два XML – это ответы на поисковые запросы, сделанные к одному из наших партнёров. В ответах лежат варианты перелётов (тег Flights) со всей необходимой информацией, чтобы отобразить билет на Aviasales.
На основе этих данных, нужно сделать вебсервис, в котором есть эндпоинты, отвечающие на следующие запросы:
- Какие варианты перелёта из DXB в BKK мы получили?
- Самый дорогой/дешёвый, быстрый/долгий и оптимальный варианты
- В чём отличия между результатами двух запросов (изменение маршрутов/условий)?
Язык реализации: Go Формат ответа: json По возможности использовать стандартную библиотеку.
Язык реализации: python3 Формат ответа: json Используемые библиотеки и инструменты — всё на твой выбор.
Оценивать будем умение выполнять задачу имея неполные данные о ней, умение самостоятельно принимать решения и качество кода.
В качестве веб-сервера использовался aiohttp, поскольку до этого его ни разу не использовал, а было желание посмотреть на него.
Вначале был реализован парсинг предоставленных файлов с помощью BeautifulSoup и перевод их в универсальные dataclass'ы. Структуру датаклассов можно посмотреть тут. Она примерно повторяет стрктуру данных из файлов.
После этого была реализована основная архитектура приложения. В архитектуру закладывалась возможность загрузки данных из разных источников
(например, у разных компаний). Интерфейс агента можно посмотреть тут.
Взаимодействие с агентами построено через дополнительный класс, который при старте системы
автоматически загружает всех доступных агентов с использованием конфига агентов, а также загружает все
таймзоны аэропортов, которые используются при парсинге времени.
При запросе информации у AgentsController
используется метод load_routes, который формирует набор корутин agent.load_routes
и запускает их параллельно.
Сам веб-сервер имеет два endpoint'a: route
и diff
. Сериализация и десериализация данных сделана с помощью библиотеки marshmallow
.
Все используемые схемы можно посмотреть тут.
Основной endpoint для получения информации о маршрутах. Параметры запроса хорошо описаны в схеме:
class FlightGetSchema(Schema):
source = fields.Str(required=True, validate=[
validate.Length(min=3, max=3),
validate.ContainsOnly(string.ascii_letters)
])
destination = fields.Str(required=True, validate=[
validate.Length(min=3, max=3),
validate.ContainsOnly(string.ascii_letters)
])
adult = fields.Integer(missing=1, validate=validate.Range(min=1))
child = fields.Integer(missing=0, validate=validate.Range(min=0))
infant = fields.Integer(missing=0, validate=validate.Range(min=0))
order_by = fields.Str(validate=OneOf(["price", "time", "optimal"]), missing="price")
reverse = fields.Bool(missing=False)
with_return = fields.Bool(missing=False)
Реализованы три возможные сортировки:
- По цене. Сортировка учитывает количество и типы пассажиров. При совпадении цены, билеты сортируются по времени.
- По времени. При совпадении времени билеты сортируются по цене.
- По оптимальности. Для расчета оптимальности используется довольно простая формула:
route.price / min_price + route.time / min_time
. То есть сортировка пытается найти идеальное соотношение цена - время.
Endpoint, который отображает новые маршруты из файла с обратными рейсами. Есть два варианта вычисления разницы:
- Использовать "базовую" информацию о рейсах (авиакомпания, номер, откуда, куда) в маршруте
- Использовать "расширенную" информацию о рейсах (авиакомпания, номер, откуда, куда, класс обсуживания, количество остановок, тип билета) в маршруте
По-умолчанию используется "базовая" информация. Для использования "расширенной" информации нужно указать параметр use_extended_info=true
- Отсутствуют тесты
- Необходимо настроить и добавить логирование
- CI на github'e
- Docker для запуска сервера
- Конфиг внутри пакета. Нужно вынести отдельно и передавать путь к конфигам через env или командную строку
Для запуска нужно склонировать репозиторий, установить package aviasales_task, используя setup.py, после чего запустить сервер командой:
python -m aviasales_task