{"id":39382277,"url":"https://github.com/rcv911/assisted_team_test","last_synced_at":"2026-01-18T03:00:58.930Z","repository":{"id":209921902,"uuid":"237282793","full_name":"rcv911/assisted_team_test","owner":"rcv911","description":"Простенький веб сервис, показывающий полезную инфу по перелётам. Основная логика построена на парсинге xml файлов. ","archived":false,"fork":false,"pushed_at":"2020-03-07T12:43:17.000Z","size":152,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-11-29T20:43:07.042Z","etag":null,"topics":["aiohttp","aiohttp-rest-api","aiohttp-server","docker","docker-compose","xml-parsing"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rcv911.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-01-30T18:54:33.000Z","updated_at":"2023-11-29T20:43:13.411Z","dependencies_parsed_at":"2023-11-29T20:43:10.710Z","dependency_job_id":"70030ecd-cbe1-4c31-a048-db23030c9d4d","html_url":"https://github.com/rcv911/assisted_team_test","commit_stats":null,"previous_names":["rcv911/assisted_team_test"],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/rcv911/assisted_team_test","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcv911%2Fassisted_team_test","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcv911%2Fassisted_team_test/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcv911%2Fassisted_team_test/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcv911%2Fassisted_team_test/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rcv911","download_url":"https://codeload.github.com/rcv911/assisted_team_test/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rcv911%2Fassisted_team_test/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28528026,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aiohttp","aiohttp-rest-api","aiohttp-server","docker","docker-compose","xml-parsing"],"created_at":"2026-01-18T03:00:34.495Z","updated_at":"2026-01-18T03:00:58.823Z","avatar_url":"https://github.com/rcv911.png","language":"Python","readme":"# assisted_team_test\nПростенький веб сервис, показывающий полезную инфу по перелётам, а также\nразницу между двумя файлами. Основная логика построена на парсинге xml файлов. \n\n## Задача\n\nЕсть два XML – это ответы на поисковые запросы, сделанные к одному из \nпартнёров. В ответах лежат варианты перелётов (тег `Flights`) со всей \nнеобходимой информацией.\n\nНужно сделать вебсервис, в котором есть эндпоинты, отвечающие на следующие \nзапросы:\n\n* Какие варианты перелёта из DXB в BKK мы получили?\n* Самый дорогой/дешёвый, быстрый/долгий и оптимальный варианты\n* В чём отличия между результатами двух запросов (изменение маршрутов/условий)?\n\nЯзык реализации: `python3`.\nФормат ответа: `json`.\nИспользуемые библиотеки и инструменты — любые на выбор.\n\n### Описание\n\nAPI со следующим набором эндпоинтов:\n\n    • /v1/parse?parameters - Получение вариантов (дорогой/дешёвый, \n                             быстрый/долгий и оптимальный) перелёта \n                             из DXB в BKK\n                             \n    • /v1/diff             - Симметричная разница между двумя файлами\n\nСервис работает на ``python 3.7``.\n\nФреймворк для написания API — ``aiohttp``. \n\nБиблиотека для создания простенького REST API ``aiohttp_rest_api``\nДокументация: [https://aiohttp-rest-api.readthedocs.io/](https://aiohttp-rest-api.readthedocs.io/)\n\nКонфиг приложения находится: [/config/config.toml](config/config.toml)\n\n## Getting started\nДля запуска необходимо выполнить команду: `docker-compose up -d`\n\nПосле запуска раскатится docker контейнер:\n\n    • Контейнер веб приложения на http://127.0.0.1 по умолчанию\n\nФайл [PostmanCollection](assisted_team_test.postman_collection.json) содержит\nпримеры запросов на все API, который можно импортнуть в Postman\n\n## Подробнее об методах API\n## v.0.1.0\n\n    • GET http://localhost/v1/parse?need_return=\u003cname\u003e\u0026action=\u003cname\u003e\n\n    need_return:\n        true - парсит файл RS_Via-3.xml с обратным направлением (параметр по умолчанию)\n        false - парсит файл RS_ViaOW.xml без обратного направления\n    \n    action:\n        cheap - варианты полётов, начиная с самого дешёвого билета (параметр по умолчанию)\n        fast - варианты билетов, начиная с самого быстрого перелёта\n        expensive - варианты полётов, начиная с самого дорогого билета\n        slow - варианты билетов, начиная с самого медленого перелёта\n        optimal - оптимальные варианты билетов \n    \n\n    • GET http://localhost/v1/diff\n   \n## v.0.1.1\n\n    • GET http://localhost/v1/onward_diff?option=\u003cid\u003e\n\n    option:\n        1 - сравнивает файл RS_Via-3.xml с RS_ViaOW.xml по тегу OnwardPricedItinerary\n        2 - сравнивает файл RS_ViaOW.xml с RS_Via-3.xml по тегу OnwardPricedItinerary\n\n- Идея парсинга ``/v1/parse`` заключается в первоначальной имитации выбора пользователя. \nИз условия задачи мне известно: пункты назначения, дата, два файла на выбор \nс необходимой информацией. Вилкой логики служит имитация выбора пользователем \nобратного направления (параметр ``need_return``). Не вижу смысла на \nодин запрос пользователя скачивать сразу два файла вариантов билета, при условии, \nчто партнёр гарантирует предоставить всю необходимую информацию. Это \nпросадка по производительности, а также не стоит забывать о том, что у меня\nне один партнёр по предоставлению информации о перелётах (но это уже за рамками \nтекущей задачи). Мне достаточно попросить пользователя указать необходимость \nобратного билета, либо же сделать по умолчанию не брать в расчёт обратное \nнаправление.\n\n- Собранные варианты перелётов учитывались из соображения - что для удобства \nпользователя лучше? Конкретно для меня важны параметры времени и цены. ``cheap``\nпокажет варианты билетов, начиная от самого дешёвого, но и в то же время быстрого по \nвремени, если цены одинаковые. ``fast`` покажет варианты билетов, начиная от самого \nбыстрого, но и в тоже время наиболее дешевого при одинаковом времени. \n``expensive`` покажет варианты билетов, начиная от самого \nдорогого, но и в тоже время наиболее быстрого по времени, если цена одинакова.\n``slow`` покажет варианты билетов, начиная от самого \nмедленного перелёта, но и в тоже время наиболее дешёвого, если время перелёта \nсовпадает. Интересный выбор ещё ``optimal``, который совпадает с вариантом \n``fast``. Почему так и почему бы не зашиться на прямые перелёты и не выделить\nэтот вариант в отдельную сортировку выборки данных? \nЕсли подумать логически, то я не встречал быстрых непрямых перелётов. \nУчитывая поведение пользователя, то он глянет максимум 5 вариантов, а может и \nменьше.   \n\n---\n\n- Идея показа разницы между файлами ``/v1/diff`` основана на симметричной разницы\nтегов и аттрибутов файлов. Теги укажут на то, какого узла иерархии не хватает. \nНапример, узла с информацией об обратных билетах ``ReturnPricedItinerary``. \nАтрибуты укажут разницу между перевозчиком ``Carrier``. Перевозчик, на самом деле,\nочень важный параметр, особенно, если он является участником крупного \nмеждународного альянса как свидетельства об авиационном здоровье. Также разница \nможет быть и в отсутствии каких-либо тарифов в ``ServiceCharges``, например, информация о стоимости\nбилета для ребёнка ``SingleChild``.\n\n---\n\n- ``/v1/onward_diff`` - отличия между файлами по тегу ``OnwardPricedItinerary``.\nНеобходимо было привязать уникальность к данным. Отправная точка ``DXB`` для всех одинакова,\nпоэтому можно прицепиться к отправному билету сравниваемого файла и сделать уникальный\nключ ``key = '{ID перевозчика}-{номер рейса}'``. Это позволить разделить данные и установить\nпорядок следования объектов для сравнения. Почему такая необходимость возникла? \nКоличество элементов в файлах может отличаться, некорректные данные могут находиться \nв одном из файлов (или же в обоих). \n\n- Полезная информация хранится в ``['differences'][key]['difference']``, где как раз указаны различия\nмежду билетами (время, номер рейса, перевозчик, класс, тип билета и т.д.). \nНапример:\n\nРазличия (показывают, что изменилось во 2-ом файле)\n\n```json\n{\n    \"text\": \"Bangkok Airways\",\n    \"ArrivalTimeStamp\": \"2018-10-28T0715\",\n     \"FlightNumber\": \"4330\",\n     \"FareBasis\": \"2820303decf751-5511-447a-aeb1-810a6b10ad7d@@$255_DXB_BOM_535_6_16:10_$255_BOM_BKK_4330_77_01:35__A2_1_1\",\n     \"id\": \"PG\",\n     \"Class\": \"Y\",\n     \"DepartureTimeStamp\": \"2018-10-28T0135\"\n} \n```\n\nБилет, который надо сравнить\n```json\n{\n    \"FlightNumber\": \"70\",\n    \"Source\": \"BOM\",\n    \"Destination\": \"BKK\",\n    \"DepartureTimeStamp\": \"2018-10-23T0840\",\n    \"ArrivalTimeStamp\": \"2018-10-23T1440\",\n    \"Class\": \"V\",\n    \"NumberOfStops\": \"0\",\n    \"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\",\n    \"WarningText\": null,\n    \"TicketType\": \"E\",\n    \"id\": \"9W\",\n    \"text\": \"JetAirways\"\n }\n\n```\nБилет, с которым сравнивают\n\n```json\n{\n    \"FlightNumber\": \"4330\",\n    \"Source\": \"BOM\",\n    \"Destination\": \"BKK\",\n    \"DepartureTimeStamp\": \"2018-10-28T0135\",\n    \"ArrivalTimeStamp\": \"2018-10-28T0715\",\n    \"Class\": \"Y\",\n    \"NumberOfStops\": \"0\",\n    \"FareBasis\": \"2820303decf751-5511-447a-aeb1-810a6b10ad7d@@$255_DXB_BOM_535_6_16:10_$255_BOM_BKK_4330_77_01:35__A2_1_1\",\n    \"WarningText\": null,\n    \"TicketType\": \"E\",\n    \"id\": \"PG\",\n    \"text\": \"Bangkok Airways\"\n}\n\n```\n\nТакже для удобства восприятия в ``['differences'][key]['ticket']`` - билет(ы), который сравниваем и\n``['differences'][key]['new_ticket']`` - билет(ы), с которым сравниваем. \n\nИмеются ещё\n``['new_tickets']`` - где хранятся новые билеты или же не вошедшие в сравнение (из сравниваемого файла) \nи ``['wrong_tickets']`` - где показаны некорректные данные (неправильная отправная точка ``DXB``). \nОба не несут информативной ценности, логику лишь загружают, но выведены для показа.\n\n### Локальный запуск приложения\n\nНастрока через PyCharm:\n\n![local_debug](images/local_debug.jpg)\n\n\n### Мысли об улучшении и проблемы, с которыми столкнулся\n\n - Проблема дубликата тегов ``Flights``. Пришлось накручивать кастомную логику \n по фильтрации\n \n - Проблема уникальности данных. Не к чему цепляться, id например и нет гарантии, \n что данные не повторяться. (по краней мере опасения имеются)\n \n - Проблема одного партнёра. Мне неизвестно как выглядят другие файлы от других \n партнёров. Предполагаю, что общего регламента по тегам, возможно, там и нет. \n Иерархии отличаются. Соответственно назревает вопрос об универсальности и \n маштабируемости. \n\n Мысли об улучшении:\n \n - Необходимость в улучшении или изменении логики сортировки. Сейчас она выглядит\n по нубски. Но в рамках MVP - сортировка работает.\n ![flake8](images/flake8.jpg)\n \n - Хардкод на два файла, можно изменить код и сделать более универсальным.\n \n - Можно добавить дополнительные параметры, например, длительность пересадки. \\\n Фильтрацию по тарифу.\n \n - Возможно стоит прикрутить ``pytest``.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frcv911%2Fassisted_team_test","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frcv911%2Fassisted_team_test","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frcv911%2Fassisted_team_test/lists"}