Иконка для избранного в web-приложении на Python и Starlette
programming
Web-приложение на Python и Starlette, разработку которого мы исследуем в этом цикле статей, впоследствии, уже в самой ближайшей перспективе, будет развёрнуто на сервер, который в свою очередь будет обслуживать web-сайт на каком-то конкретном домене. А поскольку сеть Интернет является публичным пространством, у каждого сайта в этом пространстве должны быть определены обязательные url-адреса. В этом выпуске блога я создам в приложении адреса иконки для избранного и текстового файла robots.txt.
Определяем тип контента
HTTP протокол, по которому общаются клиент и сервер в рамках разрабатываемого web-приложения, определяет форму и состав ответа сервера. В соответствии с этим протоколом, каждый ответ сервера имеет так называемые заголовки. Если посмотреть на заголовки ответа отладочного сервера на стартовой странице приложения, то на текущий момент можно увидеть следующее:
HTTP/1.1 200 OK
date: Mon, 04 Nov 2024 02:38:38 GMT
server: uvicorn
content-length: 602
content-type: text/html; charset=utf-8
Как видно, сервер в одном из заголовков своего ответа клиенту уведомляет о типе контента, который содержится в этом ответе сервера. В данном случае мы видим заголовок content-type
, в котором указан формат страницы (text/html
) и кодировка, с которой эта страница может быть прочитана. Клиент, получая ответ от сервера, рендерит страницу в полном соответствии с указанными в заголовке ответа данными.
Если обратиться к обработчику url-адреса стартовой страницы, напоминаю, что это функция представления show_index
из модуля views.py
главной подпрограммы, то мы увидим, что обработчик возвращает экземпляр класса TemplateResponse
, который в свою очередь и определяет форму и состав HTTP-ответа сервера на заданном url-адресе.
В рамках этой демонстрации я намерен создать в web-приложении ещё два дополнительных url-адреса. Первый из них по замыслу разработчика должен возвращать в ответе сервера картинку в формате .ico
, а второй — обычный текст. Естественно, что в ответах сервера на заданных url-адресах должен быть заголовок content-type
с соответствующим значением, понятным клиенту. Как это реализовать..?
Иконка для избранного
В предыдущих выпусках этого цикла статей мы видели, что подключаясь к серверу web-браузер опрашивает не только url-адрес из адресной строки, но ещё и автоматически посылает запрос на адрес /favicon.ico. Так делают все известные сегодня браузеры. Следовательно, чтобы у пользователя клиента о сайте складывалось благоприятное впечатление, на этом адресе сервер должен возвращать страницу с соответствующим статус кодом и типом контента в заголовке.
Кроме этого, в сети Интернет живут не только одушевлённые пользователи, есть в ней и целый сонм неодушевлённых обитателей. Роботы поисковых систем, например, сканируют сеть своими сенсорами в непрерывном режиме, и они обязательно зайдут на ваш сайт, просканируют его и по результатам этого сканирования сложат о нём собственное впечатление, в соответствии с которым будут ранжировать страницы вашего сайта в своей поисковой выдаче. И они в обязательном порядке опрашивают адрес /favicon.ico
.
Учитывая изложенные обстоятельства несложно сделать вывод, что адрес /favicon.ico
является обязательным для каждого сайта сети Интернет.
Файл robots.txt
Роботы поисковых систем, сканируя сайт в сети Интернет, в обязательном порядке обращаются к адресу /robots.txt
. Из файла robots.txt они узнают порядок обработки страниц сайта и некоторую другую специфическую информацию. С помощью этого файла вебмастер имеет возможность предотвратить сканирование поисковым роботом каких-то ключевых функциональных страниц сайта. Естественно, что на этом адресе сервер должен отдавать ответ с конкретным типом контента — простой текст.
Уже в ближайшей перспективе я собираюсь развернуть разрабатываемое приложение на сервер сети со статусом Сайт в стадии разработки, и на этой стадии мне необходимо будет предотвратить сканирование сайта поисковыми роботами, чтобы "сырые" по содержанию и контенту страницы не попали в поисковую выдачу. Добиться желаемого результата мне как раз и поможет robots.txt с определённым содержимым. Об этом далее...
Создаём url-адреса
Мне необходима иконка для избранного — файл соответствующего формата. Иконка для избранного является обязательным элементом дизайна сайта. Поскольку у меня нет дизайнера, а сам я напрочь лишён художественного вкуса, и любые оформительские работы для меня как ножиком по стеклу, в рамках этого цикла статей я буду повторять дизайн этого сайта в том виде, в котором он существует в сети. Поэтому я просто копирую иконку с этого сайта и размещаю файл в каталоге images
.
Мне нужны два новых url-адреса, которые необходимо создать. Конфигурация ASGI приложения хранится в "ините" базового каталога. Открываю этот файл в текстовом редакторе Vim.
$ vim webapp/__init__.py
Я собрался определить в приложении два новых url-адреса, это значит, что мне потребуется определить два новых обработчика для этих адресов. Обработчики будут храниться в модуле views.py
главной подрограммы, вписываю их имена в соответствующий импорт.
from .main.views import show_favicon, show_index, show_robots
В параметр routes
ASGI приложения добавляю два новых элемента, каждый из которых будет экземпляром библиотечного класса Route.
app = StApp(
debug=settings.get('DEBUG', cast=bool),
routes=[
Route('/', show_index, name='index'),
Route('/favicon.ico', show_favicon, name='favicon'),
Route('/robots.txt', show_robots, name='robots.txt'),
Mount('/static', app=StaticFiles(directory=static), name='static')])
Вот как выглядит файл в моём текстовом редакторе после всех внесённых изменений.
Сохраняю изменения в файл, но не спешу покидать текстовый редактор.
Файл иконки для избранного я положил в каталог images
, далее мне необходимо будет сослаться на адрес этого каталога в файловой системе моего рабочего компьютера. Открываю в текстовом редакторе файл dirs.py
из базового каталога приложения.
:split webapp/dirs.py
Дописываю в этот файл одну единственную строчку.
images = os.path.join(static, 'images')
Сохраняю изменения в файл. Пришло время создать обработчики для новых url-адресов.
Конструируем логику обработчиков
Открываю в текстовом редакторе модуль views.py
из каталога главной подпрограммы.
:tabnew webapp/main/views.py
В новых обработчиках я должен задать соответствующий тип контента каждому. Сделать это можно с помощью библиотечных классов Starlette. Иконку для избранного будет обрабатывать экземпляр класса FileResponse, а robots.txt — PlainTextResponse. Кроме этого, мне необходимо будет выразить адрес иконки для избранного в файловой системе моего рабочего компьютера в терминах Питона. Вписываю в файл следующие процедуры импорта.
import os
from starlette.responses import FileResponse, PlainTextResponse
from ..dirs import images
Создаю новую функцию представления с именем show_favicon
для обработки url-адреса иконки для избранного. Вот как она будет выглядеть.
async def show_favicon(request):
if request.method == 'GET':
return FileResponse(
os.path.join(images, 'favicon.ico'))
Здесь я просто вернул экземпляр соответствующего класса с заданным параметром. Этот параметр выражает адрес файла favicon.ico
в файловой системе компьютера.
Файл robots.txt на текущем этапе разработки я создам с помощью простой строки, передав её в качестве параметра библиотечному классу PlainTextResponse. Вот как будет выглядеть эта функция представления в своей первой редакции.
async def show_robots(request):
return PlainTextResponse('User-agent: *\nDisallow: /')
Сохраняю изменения в файл и покидаю текстовый редактор.
Обращаю ваше внимание, что на текущем этапе разработки я закрыл все страницы сайта от роботов поисковых систем. Это не окончательная редакция файла robots.txt, далее в процессе разработки я создам в приложении инструменты, с помощью которых вебмастер сможет редактировать robots.txt с помощью вебинтерфейса сайта.
Тестируем
Первое, чего я ожидаю, — это запуск отладочного сервера без сбоев и отчётов об ошибках. Запускаю отладочный сервер в терминале с активным виртуальным окружением.
$ python runserver.py
Запускаю браузер, в его окне запускаю инструменты разработчика (ctrl+shift+i
), перехожу на вкладку Network
и только после этого вбиваю url-адрес стартовой страницы приложения в адресную строку браузера, жму enter
.
Как мы видим на снимке экрана выше, в окне инструментов разработчика браузер, я использую для тестирования Google-Chrome, показал четыре ответа сервера. Для каждого ответа сервера браузер показал статус код, тип контента, размер и время загрузки. В списке присутствует в том числе и ответ на адресе /favicon.ico
. А если посмотреть на самый верх окна браузера, на вкладке можно увидеть ту самую иконку, файл которой я положил в каталог images
в самом начале этой демонстрации. С этого момента у web-приложения появилась оригинальная иконка для избранного.
А что с адресом /robots.txt
? Вбиваю в адресную строку соответствующий url и жму enter
.
Как видно на снимке экрана выше, в окне инструментов разработчика браузера можно увидеть и заголовки ответа сервера, и в данном случае в этих заголовках числится content-type
с соответствующим значением. На данный момент robots.txt запрещает индексирование всех страниц сайта всем поисковым роботам сети.
Давайте посмотрим на окно терминала, в котором я запускал отладочный сервер.
Как видно на снимке экрана выше, отладочный сервер на данный момент получил от клиента пять последовательных запросов, на которые отдал соответствующие запросам ответы со статус кодом 200
. Ошибок и сбоев не зарегистрировано. Все цели этой демонстрации полностью достигнуты.
Подводим промежуточный итог
Процесс разработки web-приложения достаточно сложен, растянут по времени и требует внимания и усидчивости. На текущем этапе проектирования я определил в web-приложении два новых url-адреса, которые являются обязательными для каждого web-сайта. У приложения появилась оригинальная иконка для избранного и текстовый файл robots.txt. А в следующем выпуске этого цикла статей мы поговорим о сторонних frontend библиотеках, которые я собираюсь использовать в проекте, и кое-что из этого списка я подключу в приложение.
В рамках этого цикла статей я планирую показать поэтапно разработку системы авторизации пользователей этого web-приложения, для этого мне потребуется подключить в приложение много других полезных инструментов. Насколько далеко я зайду в реализации этого плана, зависит от активности в блоге — ваши посещения, подписки, лайки, комментарии, донаты служат главным мотивирующим меня фактором. Все статьи цикла доступны в хронологическом порядке по метке webapp. Не оставайтесь в стороне, продолжение следует, будет интересно...