Разрабатываем web-приложение на Python3x, эпизод первый

Jazz

Опубликован:  2023-09-25T06:13:51.082856Z
Отредактирован:  2023-09-25T06:13:51.082856Z
Статус:  публичный
32
0
0

Web-разработка.., именно её мы увлечённо исследуем в этом блоге и продолжаем целенаправленно двигаться в этом направлении. Очередной выпуск блога открывает цикл статей, посвященных разработке конкретного приложения, и в нём я продемонстрирую процесс разработки в пошаговом режиме, покажу задачи, с которыми web-разработчик имеет дело на протяжении этого процесса, на каждом этапе разработки, и которые должен уметь успешно решать. Все статьи этого цикла можно отфильтровать по этой ссылке. Будет интересно...

Ставим задачу

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

Web-разработчик разрабатывает программы для web-серверов, такие программы, когда они развёрнуты на сервер и слушают сеть, обычно называют web-сервисами. И следует признать, что web-сервис - это не всегда сайт, бывает так, что web-сервис всего лишь предоставляет API для других web-сервисов, и в его ответах клиентам в качестве ContentType указан JSON или XML, и это не совсем то, что рядовые пользователи сети Интернет привыкли называть сайтами.

Итак.., в рамках этого цикла статей, я надеюсь, что моей мотивации хватит на целый цикл, мы будем изучать процесс разработки web-сервиса, который в последствии будет обслуживать сайт в сети Интернет. Разработка web-сервиса - задача довольно объёмная и трудоёмкая, просто сесть и написать такую программу не получится, её нужно разрабатывать постепенно, отлаживать, тестировать, снова разрабатывать - почти бесконечный набор итераций. Отсюда я делаю вывод, что весь процесс разработки web-сервиса будет логично и выгодно поделить на микроскопические этапы разработки и решать на каждом этапе одну маленькую задачу, которая в совокупности уместится в примерно 200-500 строчек кода. Такую выделенную задачу довольно просто отладить и несложно оттестировать.

В этой демонстрации я покажу начальный этап разработки web-сервиса, опишу элементарное взаимодействие клиента и сервера в рамках одного единственного URL-адреса и разработаю стартовую страницу web-сервиса, такую обычно называют Index Page. На текущем этапе разработки это будет всего лишь страница с информационным сообщением, которую, впрочем, на последующих этапах разработки можно будет доработать до более совершенных кондиций.

Web-сервис, который я буду разрабатывать, назову selfish, и все статьи посвященного его разработке цикла можно будет отфильтровать по одноимённой метке, ссылка уже указана выше. Разрабатывать selfish я буду на языке программирования Python3x на базе операционной системы Debian. В одной из предыдущих статей этого цикла я подготовил рабочее место программиста, и именно его сейчас и буду использовать. Уважаемый читатель, все демонстрируемые здесь действия вполне возможно, и даже будет полезно, воспроизвести на собственном компьютере, именно так я учился когда-то сам. Эта демонстрация будет опубликована на моём канале в ЯндексДзен, вопросы и пожелания приветствуются, отклики, лайки, дизлайки, комментарии и подписки на канал будут служить для меня дополнительным мотивирующим фактором. Пожалуй приступим...

Выбор web-фреймворка

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

Web - это взаимодействие клиента и сервера по протоколу HTTP. Каждый web-сервис обязан иметь в своём арсенале средства для реализации такого взаимодействия. И эти средства совершенно не обязательно разрабатывать каждый раз для каждого нового web-сервиса, обычно их объединяют в библиотеки кода и используют повторно, снова и снова, для каждого вновь разрабатываемого web-сервиса. В среде web-разработчиков такие библиотеки принято называть web-фреймворками общего назначения. Selfish - не исключение, его я буду разрабатывать на базе такой сторонней библиотеки, которая в свою очередь уже имеет все необходимые инструменты для реализации общения клиента и сервера.

Web-фреймворков общего назначения на языке программирования Python3x сегодня достаточно много, и первой задачей разработчика является выбор одного конкретного, на базе которого и будет строиться web-приложение.

Современные web-фреймворки делятся по типу ввода вывода, и в этом смысле они могут быть с блокирующим вводом выводом или с асинхронным вводом выводом. Далее я их буду называть соответственно блокирующими или асинхронными.

Среди блокирующих фреймворков наибольшую популярность получили двое: Django и Flask.

Django за счёт поддержки обширного сообщества разработчиков получил популярность у современных игроков IT-сферы. Этот фреймворк включает в себя целый набор инструментов - огромная коробка, внутри есть собственный шаблонизатор, собственная ORM и много чего ещё, за счёт чего конечному разработчику приходится писать меньше кода, но при этом необходимо внимательно и тщательно изучать официальную документацию и используемую этой библиотекой методологию. Официальный мануал Django - достаточно увесистый манускрипт, его придётся читать каждый раз, снова и снова. И очень часто конечному web-программисту приходится бороться с Django в прямом смысле этого слова. На него следует обратить внимание тем, кто хочет найти своё место в сфере IT, получить работу. Почти все работодатели на рынке труда сегодня требуют знания Django. Определённо не мой выбор.

Flask - довольно изящная штуковина. Он минималистичен, расширяем за счёт других сторонних библиотек, у него нет собственного шаблонизатора, зато есть возможность прикрутить Jinja2, у него нет собственной ORM, зато есть возможность прикрутить SQLAlchemy - и так во всём. Сегодня для Flask существует достаточное количество расширений, за счёт которых конечному web-программисту придётся писать меньше кода, в этом смысле Flask не менее эффективен, чем Django.

Главным на мой взгляд недостатком блокирующих фреймворков является необходимость делать многие долгоиграющие задачи фоновыми, с ними приходится использовать очередь задач, например, Celery. Кроме этого они работают сравнительно медленнее и хуже держат нагрузку на web-сервис. Но это, конечно же, субъективное умозаключение. В своё время я писал на Flask, он мне очень нравился, но в итоге мне захотелось перейти на асинхронный ввод вывод по некоторым соображениям практичности, и я от Flask отказался.

Вторая группа web-фреймворков - это асинхронные фреймворки. Их достаточно много сегодня, самые заметные это: aiohttp, Sanic, Starlette.

В рамках этого цикла статей я буду разрабатывать web-сервис selfish на базе библиотеки Starlette, она удобна, эффективна, обеспечивает отличное быстродействие web-сервиса, проста в использовании, но требует от конечного программиста больше кода и больше опыта. Посмотрим, чем такой выбор будет мне грозить впоследствии...

Создаём структуру каталогов приложения

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

Мне нужен терминал, запускаю, в моём случае это будет Sakura, вот как она выглядит на моём рабочем столе.

yPRZYagzOj.png

Обращаю внимание, что на текущий момент я нахожусь в домашнем каталоге текущего пользователя с именем jazz. Yes, it is me! Все разрабатываемые программы я привык хранить в одном каталоге и определил этому каталогу имя workspace - этот каталог хранится в моём "хомяке". Для selfish я создам в нём каталог с таким же именем - selfish.

$ mkdir -p workspace/selfish

Только что созданный каталог будем считать корневым каталогом для данного конкретного приложения. В корневом каталоге я создам ещё один вложенный каталог с таким же именем - selfish.

$ mkdir workspace/selfish/selfish

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

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

Базовый каталог selfish я оформлю как пакет Python, для этого создаю в нём файл "дандеринит".

$ touch workspace/selfish/selfish/__init__.py

В этом файле чуть позже я расположу пространство имён разрабатываемого web-приложения и в нём создам все необходимые для реализации поставленной задачи объекты.

Selfish в перспективе станет достаточно объёмным приложением и в своих рамках будет содержать несколько различных модулей с подпрограммами. Один из таких модулей я начну разрабатывать уже прямо сейчас, и для него создам в базовом каталоге selfish вложенный каталог с именем main.

$ mkdir workspace/selfish/selfish/main

Подпрограмма main в свою очередь тоже будет пакетом Python, в её каталоге создаю свой "дандеринит".

$ touch workspace/selfish/selfish/main/__init__.py

Кроме этого, мне потребуется файл, в котором будет храниться код разрабатываемых мной функций представления, что это такое, поговорим чуть позже. А пока создаю ещё один файл в каталоге main - views.py.

$ touch workspace/selfish/selfish/main/views.py

В одном из предыдущих выпусков этого цикла мы пришли к выводу, что web состоит из фронтэнда и бэкэнда. Фронтэнд пересекается с бэкэндом в шаблоне, который рендерит функция представления, - как правило, это почти обычный HTML-код с некоторыми отличительными признаками. Все шаблоны я буду хранить в отдельном каталоге с именем templates, который расположу в базовом каталоге selfish. Создаю его.

$ mkdir workspace/selfish/selfish/templates

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

$ touch workspace/selfish/selfish/templates/base.html

Почти у каждого web-сервиса есть статические файлы - это файлы, которые никак не изменяются в процессе функционирования web-приложения, они остаются неизменными в том виде, в котором их создал web-программист, обычно это сценарии JavaScript, таблицы стилей, шрифты, файлы изображений и т.п. Для хранения статических файлов я создам отдельный каталог с именем static и в нём вложенные каталоги с именами js, css, images. Создаю...

$ mkdir -p workspace/selfish/selfish/static/js

Чтобы каталог не был пустым, в нём создам файл base.js - он, возможно, вообще будет удалён впоследствии, но пока пусть будет.

$ touch workspace/selfish/selfish/static/js/base.js

Создаю каталог css.

$ mkdir workspace/selfish/selfish/static/css

В нём файл base.css, он тоже понадобится чуть позже, но пусть будет уже сейчас.

$ touch workspace/selfish/selfish/static/css/base.css

И, наконец, каталог images.

$ mkdir workspace/selfish/selfish/static/images

В этот каталог я положу пару файлов изображений: favicon.ico и logo.png.

Давайте посмотрим, как выглядит в результате предпринятых усилий дерево корневого каталога selfish.

$ tree workspace/selfish/

LcrfcalPNE.png

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

Создаём виртуальное окружение

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

Вхожу в корневой каталог selfish.

$ cd workspace/selfish/

Находясь в нём создаю виртуальное окружение с именем venv.

$ python3 -m venv venv

В результате выполнения этой команды в коневом каталоге selfish появился вложенный каталог с именем venv, как заказывал. Активирую это виртуальное окружение.

$ source venv/bin/activate

dQ2L3RVUP0.png

На снимке экрана можно заметить, что после выполнения этой команды приглашение командной строки в моём терминале изменилось, у него появился префикс (venv) - это имя активного виртуального окружения. Обновляю один из его ключевых компонентов.

$ pip install --upgrade wheel

Команда выдаст в терминал вот такой весёлый выхлоп.

Collecting wheel
  Obtaining dependency information for wheel from https://files.pythonhosted.org/packages/b8/8b/31273bf66016be6ad22bb7345c37ff350276cfd46e389a0c2ac5da9d9073/wheel-0.41.2-py3-none-any.whl.metadata
  Downloading wheel-0.41.2-py3-none-any.whl.metadata (2.2 kB)
Downloading wheel-0.41.2-py3-none-any.whl (64 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 64.8/64.8 kB 149.7 kB/s eta 0:00:00
Installing collected packages: wheel
Successfully installed wheel-0.41.2

Виртуальное окружение готово к работе. В процессе разработки selfish я буду обновлять его снова и снова, каждый раз, когда мне потребуется та или иная сторонняя библиотека. Все последующие действия при разработке selfish я буду выполнять в терминале, находясь в корневом каталоге selfish и с активным виртуальным окружением.

Настраиваем приложение

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

$ pip install starlette[full]

При исполнении этой команды в терминале образуется достаточно обильный выхлоп, и заканчивается он вот такой строчкой:

Successfully installed MarkupSafe-2.1.3 anyio-4.0.0 certifi-2023.7.22 h11-0.14.0 httpcore-0.18.0 httpx-0.25.0 idna-3.4 itsdangerous-2.1.2 jinja2-3.1.2 python-multipart-0.0.6 pyyaml-6.0.1 sniffio-1.3.0 starlette-0.31.1

IPoHMb8VCL.png

Web-фреймворк установлен и готов к работе. Пришло время создать ключевой объект в пространстве имён selfish - экземпляр класса Starlette. Открываю в текстовом редакторе Vim, в его графической реализации GVim файл "дандеринит" из базового каталога selfish.

$ vim -g selfish/__init__.py

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

Чтобы получить доступ к базовому каталогу selfish и его вложенным каталогам, мне потребуется модуль стандартной библиотеки Питона - os. Подключаю его в пространство имён selfish.

import os

Из библиотеки Starlette уже на старте разработки мне будут необходимы некоторые классы, подключаю их.

from starlette.applications import Starlette
from starlette.config import Config
from starlette.middleware import Middleware
from starlette.middleware.sessions import SessionMiddleware
from starlette.routing import Mount, Route
from starlette.staticfiles import StaticFiles

Чуть позже я создам первую функцию представления в файле views.py из каталога main, на текущем этапе эта функция представления не существует, я просто обозначаю намерение.

from .main.views import show_index

Обратите внимание, что процедуры импорта я сгруппировал следующим образом:

  1. Объекты стандартной библиотеки Питона;

  2. Объекты сторонних библиотек;

  3. Объекты приложения selfish - их конструирую и разрабатываю я.

Привязываю базовый каталог selfish к соответствующему объекту Python в коде приложения - base. С помощью этого объекта привязываю соответствующие вложенные в базовый каталог подкаталоги static и templates, создаю одноимённые объекты.

base = os.path.dirname(__file__)
static = os.path.join(base, 'static')
templates = os.path.join(base, 'templates')

Настройки приложения в некоторой мере придётся дифференцировать для процесса разработки и для работы приложения на сервере, для этого мне потребуется файл настроек, его ещё нет, его я создам чуть позже, но в коде "дандеринита" опять обозначаю намерение, создаю объект settings с помощью подключенного ранее класса Config и модуля os.

settings = Config(os.path.join(os.path.dirname(base), '.env'))

Здесь я указал имя файла настроек - .env, сам файл пока не существует и будет создан уже скоро.

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

middleware = [
    Middleware(
        SessionMiddleware,
        secret_key=settings.get('SECRET_KEY'),
        max_age=settings.get('SESSION_LIFETIME', cast=int))

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

app = Starlette(
    debug=settings.get('DEBUG', cast=bool),
    routes=[Route('/', show_index, name='index'),
            Mount('/static', app=StaticFiles(directory=static),name='static')],
    middleware=middleware)
app.config = settings

Здесь следует обратить особое внимание на параметр с именем routes - это список URL-адресов, в котором для каждого адреса указаны: адрес, обработчик, имя. На текущий момент я создал URL-адрес стартовой страницы с именем index и назначил этому адресу в качестве обработчика функцию show_index, которая пока не существует. Вторым объектом параметра routes указана группа адресов расположенных в каталоге static файлов. На следующих этапах разработки в этот список будут добавлены новые объекты, и таким образом только что созданное приложение может быть расширено.

Следует обратить внимание также, что свойство config только что созданного объекта app теперь ссылается на объект settings, определённый в пространстве имён ранее.

Сохраняю изменения в файл.

gsZ6O6r0N4.png

Пришло время создать файл настроек. Создаю и открываю в окне текстового редактора файл с именем .env, именно это имя я указал в параметрах класса Config при создании экземпляра settings, для этого перехожу в командный режим редактора и выполняю следующую команду.

:tabnew .env

В файл настроек я впишу пока три строчки - три параметра, которые я указал в соответствующих местах "дандеринита".

DEBUG=True
SECRET_KEY='secret key'
SESSION_LIFETIME=2592000

Сохраняю изменения в файл.

mDj7mjXtS4.png

Мне нужна функция представления с именем show_index, именно это имя я вписал в качестве обработчика в URL-адрес стартовой страницы. Опять перехожу в командный режим редактора, и открываю ещё один файл.

:tabnew selfish/main/views.py

В это файл пишу следующий код.

from starlette.responses import PlainTextResponse


async def show_index(request):
    return PlainTextResponse(
        'Сайт в стадии разработки, попробуйте зайти позже.')

Здесь я создал так называемую функцию представления - обработчик для URL-адреса с именем index. Функцию представления от любой другой функции отличают три ключевых признака:

  1. Функция представления указана в качестве обработчика на соответствующем URL-адресе в карте адресов ASGI-приложения;

  2. Функция представления принимает в качестве аргумента объект, представляющий из себя HTTP-запрос, имя этого аргумента - request;

  3. Функция представления возвращает HTTP-ответ (response).

Функция show_index имеет один аргумент - request, который является объектом, хранящим поступивший на сервер запрос от клиента. Возвращает эта функция экземпляр класса PlainTextResponse, его я включил в пространство имён файла views.py соответствующей процедурой импорта, и этот объект является HTTP-ответом с соответствующим типом контента. О типах контента мы поговорим позже в этом блоге. В данном случае ответ сервера будет содержать простой текстовый файл с одной единственной строчкой: Сайт в стадии разработки, попробуйте зайти позже.

Опять сохраняю изменения в файл.

2Ke985niQf.png

Приложение настроено в полном соответствии с начальным замыслом на текущий этап разработки.

Запускаем отладочный сервер

Теперь у меня есть ASGI-приложение, и чтобы запустить его, потребуется соответствующий ASGI-сервер, в качестве такового я буду использовать Uvicorn. Перехожу в окно терминала и устанавливаю в текущее виртуальное окружение ещё один пакет.

$ pip install 'uvicorn[standard]'

У этой команды будет обильный выхлоп, у пакета есть зависимости, все они будут получены и соответствующим образом распакованы. Заканчивается этот выхлоп вот такой строчкой.

Successfully installed click-8.1.7 httptools-0.6.0 python-dotenv-1.0.0 uvicorn-0.23.2 uvloop-0.17.0 watchfiles-0.20.0 websockets-11.0.3

Вот как выглядит мой терминал, после выполнения этой команды.

yX4jmEpZ1l.png

Возвращаюсь в окно текстового редактора, создаю и открываю файл с именем runserver.py, поскольку я нахожусь в коневом каталоге selfish, файл будет создан в нём же.

:tabnew runserver.py

В этот файл пишу следующий код.

import uvicorn

if __name__ == '__main__':
    uvicorn.run(
        'selfish:app', host='127.0.0.1',
        reload=True, port=5000, log_level='info')

Здесь в стандартной идиоме питона я вписал процедуру вызова метода run объекта uvicorn. В первом параметре этого вызова я вписал приложение app из пространства имён selfish - объект с именем app, который я создал в "дандерините" базового каталога selfish. Кроме этого я указал имя хоста - IP адрес localhost, который указан в первой строчке файла /etc/hosts моей операционной системы, сервер будет слушать этот адрес сети на порту 5000 - порт тоже указан в соответствующем параметре вызова . Сохраняю изменения в файл.

nNwUBmnoUQ.png

Перехожу в окно терминала и пробую исполнить только что созданный файл.

$ python runserver.py

UaFgKupV9C.png

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

Тестируем приложение в браузере

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

XHcdjyBvLX.png

Как видно на снимке экрана, взаимодействие клиента и сервера состоялось. Клиент отправил на сервер HTTP-запрос, сервер этот запрос обработал указанным в "дандерините" приложения обработчиком и выдал клиенту HTTP-ответ в полном соответствии с кодом обработчика - функции представления show_index. Обращаю внимание, что в окне терминала появились информационные сообщения о поступивших запросах, в которых указан метод поступившего запроса, адрес, протокол и статус-код ответа сервера. Видно, что сервер получил от клиента не один, а два запроса, и ответ на второй запрос имеет статус код 404 - ошибка. Дело в том, что для URL-адреса этого запроса у selfish пока что нет соответствующего обработчика, а клиент посылает запрос на этот адрес автоматом по-умолчанию. Но об этом мы обязательно поговорим чуть позже в следующих выпусках этого блога и обязательно исправим 404 на этом адресе.

В карте URL-адресов selfish указана ещё и группа адресов для файлов из каталога static, давайте посмотрим, что покажет клиент на соответствующий запрос.

7H03PKAAFM.png

Файл base.css уже существует в иерархии каталогов selfish, но не содержит ничего, клиент показал пустое окно, в то же время сервер определил для ответа на этот запрос статус код 200. Таким образом я делаю вывод, что сервер уже на текущий момент может обслуживать файлы из каталога static.

Увы, но на текущем этапе пока больше тестировать нечего. Все цели этой демонстрации достигнуты, взаимодействие клиента и сервера описано кодом Python3x и реализовано в достаточной для текущего этапа мере. Теперь у меня есть ASGI-приложение, отладочный сервер, и я могу сосредоточить своё внимание на последующей разработке кода этого приложения, о чём я обязательно расскажу в следующих выпусках этого блога. И на процессе ручного тестирования я намерен сосредоточить более пристальное внимание. Скоро...

Отключаю отладочный сервер клавиатурным сочетанием ctrl+c в окне терминала.

RFJB5kVCRT.png

Начальный этап разработки можно считать завершенным.

Заводим приложение в Git

Код приложения на каждом новом этапе разработки будет изменяться и дорабатываться в соответствии с поставленной на конкретном этапе разработки задачей, в результате чего будет появляться новая версия кода. Управлять версиями проще всего с помощью соответствующей программы, в рамках этого цикла статей я буду работать с Git. Давайте посмотрим, как создаётся git-репозиторий для разрабатываемых программ.

На текущий момент у меня есть корневой каталог selfish - он и будет выполнять роль git-репозитория. И в этом каталоге уже сейчас есть файлы, которые не должны быть включены в git и не должны попасть на Git-сервер. Для реализации такой возможности нужно создать в корневом каталоге selfish соответствующий файл, в котором будет указан список исключений для Git.

Перехожу в окно текстового редактора, и в командном режиме выполняю вот такую команду.

:tabnew .gitignore

В результате чего в корневом каталоге selfish будет создан файл с именем .gitignore. Пишу в этот файл следующий код.

__pycache__
*.pyc
*.swp
.env
venv/

Здесь я перечислил имена хранящихся в коневом каталоге вложенных каталогов и расширения файлов, которые не должны попасть в Git. Сохраняю изменения в файл.

qA98UhdkT4.png

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

:tabnew README.md

Здесь я не буду показывать содержание созданного и отредактированного файла, его можно будет увидеть в моём профиле на github.com.

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

$ pip freeze > requirements.txt

Имя файла настроек приложения - .env, попало в список исключений Git, а это значит, что на сервере файл настроек нужно будет как-то воспроизвести вновь. Для этого создаю шаблон этого файла.

$ cp .env env_template

И вот как в итоге выглядит список хранящихся в корневом каталоге selfish каталогов и файлов.

$ ls -1a

4nsdRxUyQp.png

Файлы с расширением .swp являются созданными GVim резервными копиями и существуют до тех пор, пока соответствующий буфер в редакторе не будет закрыт, это расширение я вписал в список .gitignore, эти файлы не попадут в git.

Создаю git-репозиторий.

$ git init .

Добавляю в него все созданные мной файлы на текущем этапе проектирования web-сервиса.

$ git add .

И делаю первый коммит.

$ git commit -m"Start the application"

Актуальный на текущий момент код приложения можно увидеть в моём профиле на github.com.

Подводим итог

В этой демонстрации я создал новое ASGI-приложение, запустил его с помощью ASGI-сервера, протестировал вновь созданные в карте приложения URL-адреса и продемонстрировал весь процесс разработки в пошаговом режиме. Полученное в итоге ASGI-приложение можно расширять, добавлять в него новые URL-адреса и обработчики, таким образом решая поставленные перед программистом задачи, отлаживая и тестируя вновь разработанный код на каждом последующем этапе разработки. Некоторые приёмы отладки и тестирования web-приложения я покажу в следующих выпусках этого блога. Продолжение следует, будет интересно...

Заключение

Уважаемый читатель, я не знаю, насколько интересен изложенный здесь материал, и поэтому надеюсь на ваш отклик. Ваши комментарии, вопросы, лайки, дизлайки, подписки на канал CodeJ в ЯндексДзен для меня будут мотивирующим фактором. Чем больше будет откликов, тем чаще я буду публиковать продолжение этого цикла статей. И наоборот, если откликов не будет совсем, я пойму, что публикуемый здесь материал никому не интересен, не нужен, и брошу это гиблое дело, а на досуге займусь чем-нибудь более полезным. Как-то так...

Метки:  web, vim, selfish, python3x, gvim, starlette, uvicorn, asgi