Skip to content
This repository has been archived by the owner on Mar 22, 2021. It is now read-only.

EnotYoyo/aviasales_task

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Тестовое задание для AviaSales

Условие

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

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

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

Язык реализации: Go Формат ответа: json По возможности использовать стандартную библиотеку.

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

Оценивать будем умение выполнять задачу имея неполные данные о ней, умение самостоятельно принимать решения и качество кода.

Решение

В качестве веб-сервера использовался aiohttp, поскольку до этого его ни разу не использовал, а было желание посмотреть на него.

Вначале был реализован парсинг предоставленных файлов с помощью BeautifulSoup и перевод их в универсальные dataclass'ы. Структуру датаклассов можно посмотреть тут. Она примерно повторяет стрктуру данных из файлов.

После этого была реализована основная архитектура приложения. В архитектуру закладывалась возможность загрузки данных из разных источников (например, у разных компаний). Интерфейс агента можно посмотреть тут. Взаимодействие с агентами построено через дополнительный класс, который при старте системы автоматически загружает всех доступных агентов с использованием конфига агентов, а также загружает все таймзоны аэропортов, которые используются при парсинге времени. При запросе информации у AgentsController используется метод load_routes, который формирует набор корутин agent.load_routes и запускает их параллельно.

Сам веб-сервер имеет два endpoint'a: route и diff. Сериализация и десериализация данных сделана с помощью библиотеки marshmallow. Все используемые схемы можно посмотреть тут.

Route

Основной 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. То есть сортировка пытается найти идеальное соотношение цена - время.

Diff

Endpoint, который отображает новые маршруты из файла с обратными рейсами. Есть два варианта вычисления разницы:

  • Использовать "базовую" информацию о рейсах (авиакомпания, номер, откуда, куда) в маршруте
  • Использовать "расширенную" информацию о рейсах (авиакомпания, номер, откуда, куда, класс обсуживания, количество остановок, тип билета) в маршруте

По-умолчанию используется "базовая" информация. Для использования "расширенной" информации нужно указать параметр use_extended_info=true

Что не сделано

  • Отсутствуют тесты
  • Необходимо настроить и добавить логирование
  • CI на github'e
  • Docker для запуска сервера
  • Конфиг внутри пакета. Нужно вынести отдельно и передавать путь к конфигам через env или командную строку

Запуск

Для запуска нужно склонировать репозиторий, установить package aviasales_task, используя setup.py, после чего запустить сервер командой:

python -m aviasales_task

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages