Программа работает только у автора: как сделать из скрипта на Python удобный сервис

Маша отвечает за товарный каталог интернет-магазина и готовит данные к загрузке на сайт. В её файле несколько тысяч строк с названиями, ценами и остатками. Заполняя каталог, она где-то пропустила цену, а один товар случайно записала дважды. Теперь Маше нужно найти эти ошибки, иначе неверные данные попадут на сайт магазина.

Чтобы ей не пришлось просматривать весь каталог глазами, разработчик Андрей из команды магазина написал скрипт на Python — небольшую программу для проверки файла. Программа составляет список замечаний, по которому Маша может быстро найти и исправить проблемные записи.

Но Андрей пока настроил программу только на своём компьютере. Поэтому Маша отправляет ему каждый новый каталог и ждёт результата. Если Андрей занят другой работой, проверка откладывается, а вместе с ней задерживается и подготовка товаров.

Андрей решает дать Маше возможность запускать проверку самостоятельно. Для этого он хочет сделать страницу, на которой она загрузит файл и получит отчёт. На таком вымышленном примере разберём, как локальная программа превращается в небольшой веб-сервис и какие задачи приходится решать разработчику.

Дмитрий Игнатьев
Главный редактор Учи.Онлайн

Как Маша сможет пользоваться программой сама

Андрею нужно связать свою программу со страницей сайта. На странице он размещает выбор файла и кнопку «Проверить», а программу настраивает так, чтобы она принимала загруженный каталог и возвращала найденные замечания.

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

Так Маша получает тот же полезный отчёт, но больше не ждёт, когда Андрей сможет запустить проверку вручную. Программу выполняет компьютер, на котором работает сайт, поэтому на Машином компьютере достаточно браузера. Устанавливать Python и изучать команды ей не приходится.

Такой переход имеет смысл, если программой пользуются регулярно. В нашем магазине Маша проверяет новые каталоги постоянно, а позже к ней могут присоединиться коллеги. Если бы файл требовалось проверить один раз, Андрей мог бы просто помочь ей без создания сайта. Здесь же он тратит время на сервис, чтобы не участвовать лично в каждой следующей проверке.

Что должно остаться прежним после появления сайта

Получить файл через страницу — только часть работы. Андрею нужно убедиться, что программа по-прежнему правильно проверяет товары. Для этого он берёт небольшой каталог, где каждую ошибку легко заметить, и сравнивает результаты до и после изменения.

Пусть в примере будет четыре товарные записи:

  • Лампа с артикулом A101: цена 1 200 рублей, остаток 8 штук.
  • Кружка с артикулом A102: цена пропущена, остаток 12 штук.
  • Блокнот с артикулом A103: цена 350 рублей, остаток минус 2 штуки.
  • Та же лампа A101 записана второй раз с прежней ценой и остатком.

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

В каталоге из четырёх товарных записей у второй отсутствует цена, у третьей отрицательный остаток, а четвёртая повторяет артикул A101
В каталоге из четырёх товарных записей у второй отсутствует цена, у третьей отрицательный остаток, а четвёртая повторяет артикул A101

Чтобы не запутаться при доработке, Андрей отделяет саму проверку от остальных действий программы. Одна часть отвечает за поиск замечаний, другая — за получение файла, третья — за показ отчёта. Тогда он может менять страницу, не переписывая правила проверки товаров.

Работу с файлами, проверками и обработкой ошибок вы освоите на курсе «Python-разработчик» от Skillfactory. Обучение начинается с основ Python, затем переходит к базам данных и созданию веб-приложений. Эти знания помогают развивать такую программу постепенно: сохранить полезную проверку и добавить к ней способ работы, удобный другим людям.

Маленький каталог пригодится Андрею и дальше. После очередной доработки он снова передаст его программе и проверит результат. Если замечание о пропущенной цене исчезнет, Андрей заметит проблему до того, как Маша загрузит несколько тысяч настоящих товаров.

Как помочь человеку выбрать подходящий файл

Пока Андрей сам запускал программу, он знал, какие каталоги она умеет читать. Маша может этого не знать. У неё на компьютере есть старые выгрузки, рабочие таблицы и файлы поставщиков, и внешне они похожи. Поэтому одного предложения «Загрузите файл» недостаточно.

Андрей добавляет на страницу короткую инструкцию. В ней он указывает, какой формат принимает программа и какие сведения нужны о каждом товаре. Для примера выберем CSV — формат для передачи табличных данных. В каталоге должны быть столбцы с артикулом, названием, ценой и остатком. Рядом Андрей размещает образец, с которым Маша сможет сравнить свой файл.

Если Маша выберет другую выгрузку и в ней не окажется цен, программа объяснит причину отказа: «Не найден столбец “Цена”. Проверьте файл или скачайте образец». По такому сообщению понятно, что делать дальше. Общее «Ошибка обработки» лишь вернуло бы Машу к прежней привычке спрашивать Андрея, что случилось.

Чтобы показывать эти подсказки, Андрей сначала проверяет сам файл: можно ли его прочитать и есть ли нужные столбцы. Только после этого программа начинает искать ошибки в товарах. Такой порядок помогает различать две ситуации: человек прислал неподходящий документ или прислал правильный каталог, в котором нужно исправить отдельные записи.

Получение файла через сайт разработчику не обязательно создавать с нуля. Например, в Django — наборе готовых инструментов для сайтов на Python — предусмотрен механизм загрузки файлов. Андрей может использовать его, а затем добавить правила именно своего магазина.

Что изменится, когда файл загрузит второй сотрудник

Маша уже умеет проверять каталог сама. Это замечает Денис, который готовит товары другого отдела, и тоже просит доступ к сервису. Он загружает свой файл с двумя корректными записями. Случайно оба сотрудника назвали файлы одинаково — catalog.csv.

Пока Андрей пользовался программой один, она могла каждый раз сохранять результат в один и тот же файл. Но если оставить такой порядок на сайте, отчёт Дениса заменит Машин. Маша откроет страницу и увидит «Замечаний нет», хотя её каталог по-прежнему содержит три ошибки. Программа не сломается заметным образом — она просто покажет не тому человеку не тот результат.

Чтобы этого не случилось, Андрей сохраняет каждую проверку отдельно. Сервис запоминает, кто загрузил файл и какой отчёт к нему относится. Поэтому одинаковые названия больше не мешают: у Маши остаются четыре проверенные записи и три замечания, у Дениса — две записи без замечаний.

Маша и Денис загружают файлы с одинаковым именем, но получают каждый свой отчёт в личном разделе
Маша и Денис загружают файлы с одинаковым именем, но получают каждый свой отчёт в личном разделе

Для работы с этими результатами Андрей добавляет сотрудникам личные разделы. После входа Маша видит свою историю загрузок, а Денис — свою. Они могут вернуться к прошлой проверке и скачать нужный отчёт, не разыскивая его среди чужих файлов.

При этом скрыть чужие отчёты из списка недостаточно. Сайт должен проверить разрешение и тогда, когда человек открывает прямую ссылку на файл. Этот принцип описан в рекомендациях OWASP по доступу к данным. В нашем примере он означает простую вещь: сервис не отдаст Денису Машин каталог только потому, что тот узнал его адрес.

Чтобы история не исчезала при перезапуске программы, Андрей сохраняет сведения о проверках в базе данных — организованном хранилище записей. Файлы и отчёты он тоже хранит постоянно, а не только пока программа открыта. Тогда сотрудники могут рассчитывать, что вчерашний результат будет доступен и завтра.

Как объяснить результат проверки

Теперь Маша может сама загрузить файл и найти свой отчёт. Но отчёт ещё нужно сделать полезным: показать, какие именно записи требуют исправления и почему. Иначе Андрей лишь заменит просьбу «Проверь файл» новой просьбой — «Объясни, что получилось».

Поэтому для кружки программа выводит артикул A102 и сообщение «Не указана цена». Для блокнота — A103 и «Отрицательный остаток». Для второй записи лампы — A101 и сообщение о повторе. Рядом Андрей добавляет номер товарной записи, чтобы Маша быстрее нашла её в исходном файле. В нашем примере заголовок не входит в нумерацию: кружка — вторая запись, блокнот — третья, повтор лампы — четвёртая.

Отдельно нужно объяснить, закончила ли работу сама программа. Если она просмотрела все четыре записи и сохранила три замечания, проверка завершена. Это не означает, что с каталогом всё хорошо: программа как раз нашла ошибки, которые Маша должна исправить.

Бывает и другая ситуация: программа остановилась, потому что не смогла прочитать весь файл. Тогда полного отчёта нет и количество замечаний неизвестно. Поэтому вместо «Замечаний нет» Андрей показывает «Проверку не удалось завершить» и объясняет, как повторить её или обратиться за помощью.

Слева проверка завершилась и нашла три замечания в каталоге, справа программа остановилась и готового отчёта нет
Слева проверка завершилась и нашла три замечания в каталоге, справа программа остановилась и готового отчёта нет

Так Маша различает два результата. После завершённой проверки она исправляет товары по списку. После сбоя сначала выясняет, почему проверка не состоялась. Сообщение на странице подсказывает действие, а не заставляет угадывать смысл зелёной или красной рамки.

Связывать поведение страницы с работой программы вы научитесь на курсе «Fullstack-разработчик на Python» от Skillfactory. В обучении соединены JavaScript для браузерной части, Python для серверной и работа с базами данных. Эти навыки помогают продумать весь путь человека: он выбирает файл, понимает ход проверки и получает нужный отчёт.

Простую страницу с загрузкой может сделать и Python-разработчик. Когда в сервисе появляются история, поиск по замечаниям и обновление результатов, работа со страницами становится сложнее. Фуллстек-разработчик умеет развивать обе части: и то, что видит человек в браузере, и программу, которая выполняет проверку.

Что делать, если приходится долго ждать отчёт

Четыре записи программа проверяет быстро, поэтому в первой версии Маша может дождаться результата на странице. Андрей сначала смотрит, сколько времени занимает работа с настоящими файлами и что происходит, когда каталог загружают несколько сотрудников одновременно.

Если ожидание становится долгим, он меняет порядок обработки. Сайт сначала принимает файл и сохраняет его. Затем программа продолжает проверку независимо от открытой страницы, а готовый отчёт добавляет в личный раздел пользователя. Такой способ называют фоновой обработкой.

Для Маши это означает, что она может загрузить большой каталог и вернуться к другим делам. Закрывать браузер не страшно: уже принятый файл продолжит проверяться. Позже она откроет свой раздел и увидит, готов ли отчёт. Похожий подход на примере подготовки выгрузки показывает Мигель Гринберг в авторском разборе фоновых задач.

Весь порядок теперь выглядит так:

  1. Маша загружает каталог, а сайт сохраняет его для проверки.
  2. Программа проверяет файл, даже если Маша закрыла страницу.
  3. После завершения сервис сохраняет отчёт в её личном разделе.
  4. Маша возвращается на сайт и открывает результат.
Пользователь загружает каталог, программа проверяет его без открытой страницы, а готовый отчёт сохраняется в личном кабинете
Пользователь загружает каталог, программа проверяет его без открытой страницы, а готовый отчёт сохраняется в личном кабинете

Чтобы такой порядок действительно работал, Андрею нужно продумать и неудачные случаи. Что увидит Маша, если проверка остановится? Как он сам об этом узнает? Можно ли будет запустить её снова? Поэтому он добавляет фоновую обработку, когда в ней появляется потребность, и проверяет весь путь до готового отчёта.

Где программа будет работать постоянно

Есть ещё одна зависимость от автора, которую нужно убрать. Если сайт работает на Андреевом ноутбуке, сотрудники теряют доступ каждый раз, когда он выключает компьютер. Поэтому для постоянной работы Андрей размещает сервис на сервере — компьютере, доступном пользователям независимо от его личного ноутбука.

На сервере он настраивает программу, хранение файлов и доступ к базе данных. Затем проверяет тот же путь, который пройдут Маша и Денис: вход, загрузку каталога, получение отчёта и открытие старого результата. Успешный запуск на своём компьютере ещё не показывает, что новая установка работает так же.

Для подготовки Django-приложения есть официальные рекомендации по запуску. Они помогают разработчику проверить настройки, которые отличаются от привычного режима разработки. Пользователю эти настройки знать не нужно, но от них зависит, сможет ли он работать с сервисом каждый день.

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

Нужен и способ восстановить данные при поломке или случайном удалении. Для этого Андрей организует резервное копирование и проверяет восстановление. Важно вернуть не только список прошлых проверок, но и связанные с ним файлы: запись «Отчёт готов» мало помогает, если сам отчёт потерялся.

Как понять, что сервис стал удобнее прежнего скрипта

Для первой проверки Андрей предлагает Маше пройти весь путь самостоятельно. Он смотрит, понимает ли она, какой файл выбрать, может ли прочитать замечания и находит ли старый результат. Если на каждом шаге требуется его подсказка, значит, часть объяснений пока существует только у него в голове.

Затем Андрей проверяет случаи, которые появились вместе с сайтом. Разные файлы Маши и Дениса не должны заменять друг друга. Неподходящий документ должен вызывать понятное сообщение. Обновление страницы не должно запускать уже готовую проверку заново, а перезапуск сервиса — стирать историю.

В версии с долгой обработкой Маша отдельно проверяет обещанный порядок: загружает файл, закрывает страницу и возвращается за результатом. Так Андрей убеждается, что сделал не только удобную надпись, но и работающую возможность.

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

Создание программ на Python, работу с файлами и серверной логикой вы сможете освоить на курсе «Python-разработчик». Разработку пользовательского интерфейса и его связь с серверной частью — на курсе «Fullstack-разработчик на Python».