Skip to content

rcv911/assisted_team_test

Repository files navigation

assisted_team_test

Простенький веб сервис, показывающий полезную инфу по перелётам, а также разницу между двумя файлами. Основная логика построена на парсинге xml файлов.

Задача

Есть два XML – это ответы на поисковые запросы, сделанные к одному из партнёров. В ответах лежат варианты перелётов (тег Flights) со всей необходимой информацией.

Нужно сделать вебсервис, в котором есть эндпоинты, отвечающие на следующие запросы:

  • Какие варианты перелёта из DXB в BKK мы получили?
  • Самый дорогой/дешёвый, быстрый/долгий и оптимальный варианты
  • В чём отличия между результатами двух запросов (изменение маршрутов/условий)?

Язык реализации: python3. Формат ответа: json. Используемые библиотеки и инструменты — любые на выбор.

Описание

API со следующим набором эндпоинтов:

• /v1/parse?parameters - Получение вариантов (дорогой/дешёвый, 
                         быстрый/долгий и оптимальный) перелёта 
                         из DXB в BKK
                         
• /v1/diff             - Симметричная разница между двумя файлами

Сервис работает на python 3.7.

Фреймворк для написания API — aiohttp.

Библиотека для создания простенького REST API aiohttp_rest_api Документация: https://aiohttp-rest-api.readthedocs.io/

Конфиг приложения находится: /config/config.toml

Getting started

Для запуска необходимо выполнить команду: docker-compose up -d

После запуска раскатится docker контейнер:

• Контейнер веб приложения на http://127.0.0.1 по умолчанию

Файл PostmanCollection содержит примеры запросов на все API, который можно импортнуть в Postman

Подробнее об методах API

v.0.1.0

• GET http://localhost/v1/parse?need_return=<name>&action=<name>

need_return:
    true - парсит файл RS_Via-3.xml с обратным направлением (параметр по умолчанию)
    false - парсит файл RS_ViaOW.xml без обратного направления

action:
    cheap - варианты полётов, начиная с самого дешёвого билета (параметр по умолчанию)
    fast - варианты билетов, начиная с самого быстрого перелёта
    expensive - варианты полётов, начиная с самого дорогого билета
    slow - варианты билетов, начиная с самого медленого перелёта
    optimal - оптимальные варианты билетов 


• GET http://localhost/v1/diff

v.0.1.1

• GET http://localhost/v1/onward_diff?option=<id>

option:
    1 - сравнивает файл RS_Via-3.xml с RS_ViaOW.xml по тегу OnwardPricedItinerary
    2 - сравнивает файл RS_ViaOW.xml с RS_Via-3.xml по тегу OnwardPricedItinerary
  • Идея парсинга /v1/parse заключается в первоначальной имитации выбора пользователя. Из условия задачи мне известно: пункты назначения, дата, два файла на выбор с необходимой информацией. Вилкой логики служит имитация выбора пользователем обратного направления (параметр need_return). Не вижу смысла на один запрос пользователя скачивать сразу два файла вариантов билета, при условии, что партнёр гарантирует предоставить всю необходимую информацию. Это просадка по производительности, а также не стоит забывать о том, что у меня не один партнёр по предоставлению информации о перелётах (но это уже за рамками текущей задачи). Мне достаточно попросить пользователя указать необходимость обратного билета, либо же сделать по умолчанию не брать в расчёт обратное направление.

  • Собранные варианты перелётов учитывались из соображения - что для удобства пользователя лучше? Конкретно для меня важны параметры времени и цены. cheap покажет варианты билетов, начиная от самого дешёвого, но и в то же время быстрого по времени, если цены одинаковые. fast покажет варианты билетов, начиная от самого быстрого, но и в тоже время наиболее дешевого при одинаковом времени. expensive покажет варианты билетов, начиная от самого дорогого, но и в тоже время наиболее быстрого по времени, если цена одинакова. slow покажет варианты билетов, начиная от самого медленного перелёта, но и в тоже время наиболее дешёвого, если время перелёта совпадает. Интересный выбор ещё optimal, который совпадает с вариантом fast. Почему так и почему бы не зашиться на прямые перелёты и не выделить этот вариант в отдельную сортировку выборки данных? Если подумать логически, то я не встречал быстрых непрямых перелётов. Учитывая поведение пользователя, то он глянет максимум 5 вариантов, а может и меньше.


  • Идея показа разницы между файлами /v1/diff основана на симметричной разницы тегов и аттрибутов файлов. Теги укажут на то, какого узла иерархии не хватает. Например, узла с информацией об обратных билетах ReturnPricedItinerary. Атрибуты укажут разницу между перевозчиком Carrier. Перевозчик, на самом деле, очень важный параметр, особенно, если он является участником крупного международного альянса как свидетельства об авиационном здоровье. Также разница может быть и в отсутствии каких-либо тарифов в ServiceCharges, например, информация о стоимости билета для ребёнка SingleChild.

  • /v1/onward_diff - отличия между файлами по тегу OnwardPricedItinerary. Необходимо было привязать уникальность к данным. Отправная точка DXB для всех одинакова, поэтому можно прицепиться к отправному билету сравниваемого файла и сделать уникальный ключ key = '{ID перевозчика}-{номер рейса}'. Это позволить разделить данные и установить порядок следования объектов для сравнения. Почему такая необходимость возникла? Количество элементов в файлах может отличаться, некорректные данные могут находиться в одном из файлов (или же в обоих).

  • Полезная информация хранится в ['differences'][key]['difference'], где как раз указаны различия между билетами (время, номер рейса, перевозчик, класс, тип билета и т.д.). Например:

Различия (показывают, что изменилось во 2-ом файле)

{
    "text": "Bangkok Airways",
    "ArrivalTimeStamp": "2018-10-28T0715",
     "FlightNumber": "4330",
     "FareBasis": "2820303decf751-5511-447a-aeb1-810a6b10ad7d@@$255_DXB_BOM_535_6_16:10_$255_BOM_BKK_4330_77_01:35__A2_1_1",
     "id": "PG",
     "Class": "Y",
     "DepartureTimeStamp": "2018-10-28T0135"
} 

Билет, который надо сравнить

{
    "FlightNumber": "70",
    "Source": "BOM",
    "Destination": "BKK",
    "DepartureTimeStamp": "2018-10-23T0840",
    "ArrivalTimeStamp": "2018-10-23T1440",
    "Class": "V",
    "NumberOfStops": "0",
    "FareBasis": "2820231f40c802-03e6-4655-9ece-0fb1ad670b5c@@$255_DXB_BOM_535_6_15:10_$255_BOM_BKK_70_6_08:40_$255_BKK_BOM_61_6_08:55_$255_BOM_DXB_544_6_18:50__A2_0_0",
    "WarningText": null,
    "TicketType": "E",
    "id": "9W",
    "text": "JetAirways"
 }

Билет, с которым сравнивают

{
    "FlightNumber": "4330",
    "Source": "BOM",
    "Destination": "BKK",
    "DepartureTimeStamp": "2018-10-28T0135",
    "ArrivalTimeStamp": "2018-10-28T0715",
    "Class": "Y",
    "NumberOfStops": "0",
    "FareBasis": "2820303decf751-5511-447a-aeb1-810a6b10ad7d@@$255_DXB_BOM_535_6_16:10_$255_BOM_BKK_4330_77_01:35__A2_1_1",
    "WarningText": null,
    "TicketType": "E",
    "id": "PG",
    "text": "Bangkok Airways"
}

Также для удобства восприятия в ['differences'][key]['ticket'] - билет(ы), который сравниваем и ['differences'][key]['new_ticket'] - билет(ы), с которым сравниваем.

Имеются ещё ['new_tickets'] - где хранятся новые билеты или же не вошедшие в сравнение (из сравниваемого файла) и ['wrong_tickets'] - где показаны некорректные данные (неправильная отправная точка DXB). Оба не несут информативной ценности, логику лишь загружают, но выведены для показа.

Локальный запуск приложения

Настрока через PyCharm:

local_debug

Мысли об улучшении и проблемы, с которыми столкнулся

  • Проблема дубликата тегов Flights. Пришлось накручивать кастомную логику по фильтрации

  • Проблема уникальности данных. Не к чему цепляться, id например и нет гарантии, что данные не повторяться. (по краней мере опасения имеются)

  • Проблема одного партнёра. Мне неизвестно как выглядят другие файлы от других партнёров. Предполагаю, что общего регламента по тегам, возможно, там и нет. Иерархии отличаются. Соответственно назревает вопрос об универсальности и маштабируемости.

Мысли об улучшении:

  • Необходимость в улучшении или изменении логики сортировки. Сейчас она выглядит по нубски. Но в рамках MVP - сортировка работает. flake8

  • Хардкод на два файла, можно изменить код и сделать более универсальным.

  • Можно добавить дополнительные параметры, например, длительность пересадки.
    Фильтрацию по тарифу.

  • Возможно стоит прикрутить pytest.

About

Простенький веб сервис, показывающий полезную инфу по перелётам. Основная логика построена на парсинге xml файлов.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors