Django 42. Запуск Django-проекта на VPS
Автор: Иван Ашихмин
Вот мы и добрались до запуска нашего проекта на сервере.
Этот пост – первый из двух, посвященных данной теме. В нём мы с вами подготовим Django для работы в Docker-контейнере и запустим его на VPS на встроенном веб-сервере. В следующем посте мы объединим Django, PostgreSQL, NGINX и Telegram-бота в одном Docker compose-сервисе.
Пост является частью серии постов "Сайт на Django", и всё происходящее будет демонстрироваться на примере того, что мы делали на протяжении 41-го поста. Кроме того, он будет частично дублировать пост "AIOgram3 17. Подготовка к разворачиванию на сервере" с поправкой на особенности Django.
Приступим.
Переменные окружения.
Автор: Иван Ашихмин
Вот мы и добрались до запуска нашего проекта на сервере.
Этот пост – первый из двух, посвященных данной теме. В нём мы с вами подготовим Django для работы в Docker-контейнере и запустим его на VPS на встроенном веб-сервере. В следующем посте мы объединим Django, PostgreSQL, NGINX и Telegram-бота в одном Docker compose-сервисе.
Пост является частью серии постов "Сайт на Django", и всё происходящее будет демонстрироваться на примере того, что мы делали на протяжении 41-го поста. Кроме того, он будет частично дублировать пост "AIOgram3 17. Подготовка к разворачиванию на сервере" с поправкой на особенности Django.
Приступим.
Переменные окружения.
🔥4
Переменные окружения позволят прописать значения, такие, как логин и пароль базы данных, секретный ключ или данные от почтового сервера, в специальном файле
Для того чтобы всё продолжало работать локально, установим библиотеку
Не забудьте добавить установленную библиотеку в файл
В корне проекта создадим файл
В самом начале файла
Для получения данных из переменных окружения мы воспользуемся методом
Нам необходимо заменить значения следующих переменных на указанную выше строку, сделав ключом имя переменной, а её текущее содержимое прописать в
-
-
-
-
-
-
-
-
-
Пример замены в
Обратите внимание на параметр
Пример
Обратите внимание на формат
Кроме того, необходимо изменить параметр
После того, как вынесли все важные данные из
Dockerfile.
Следующим шагом будет создание
Создайте файл
Разберём по порядку:
-
.env (dotenv). Таким образом можно собрать все важные данные в одном файле без необходимости прописывать их непосредственно в коде (хардкодить).Для того чтобы всё продолжало работать локально, установим библиотеку
python-dotenv, выполнив команду:pip install python-dotenv
Не забудьте добавить установленную библиотеку в файл
requirements.txt!В корне проекта создадим файл
.env и откроем файл settings.py в директории проекта.В самом начале файла
settings.py после импортов добавим вызов функции load_dotenv(). Это необходимо, чтобы данные из .env-файла подтягивались при локальном запуске. На сервере это не нужно.from dotenv import load_dotenv
load_dotenv()
Для получения данных из переменных окружения мы воспользуемся методом
.get('ключ') из функции environ() в пакете os – os.environ.get('ключ'), где ключ – это переменная в .env-файле.Нам необходимо заменить значения следующих переменных на указанную выше строку, сделав ключом имя переменной, а её текущее содержимое прописать в
.env-файле:-
SECRET_KEY.-
NAME.-
USER.-
PASSWORD.-
HOST.-
PORT.-
EMAIL_HOST.-
EMAIL_HOST_USER.-
EMAIL_HOST_PASSWORD.Пример замены в
settings.py:SECRET_KEY = os.environ.get('SECRET_KEY')
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"NAME": os.environ.get('DB_NAME'),
"USER": os.environ.get('DB_USER'),
"PASSWORD": os.environ.get('DB_PASSWORD'),
"HOST": os.environ.get('DB_HOST'),
"PORT": int(os.environ.get('DB_PORT')),
}
}
Обратите внимание на параметр
PORT. Он приведён к типу int, поскольку по умолчанию все данные из переменных окружения – строки.Пример
.env-файла:SECRET_KEY=abcde...
DB_NAME=db_name
DB_USER=db_user
DB_PASSWORD=db_password
DB_HOST=postgres
DB_PORT=5432
Обратите внимание на формат
имя_переменной=значение_переменной, без кавычек.Кроме того, необходимо изменить параметр
ALLOWED_HOSTS, прописав в него IP-адрес VPS, локальный адрес (127.0.0.1) и адрес домена, если он подключен к VPS. Должно быть примерно так:ALLOWED_HOSTS = ["127.0.0.1", "pressanybutton.ru", "0.0.0.0"]
# Вместо 0.0.0.0 пропишите IP-адрес вашего VPS.
После того, как вынесли все важные данные из
settings.py в .env, можете проверить, что всё работает как прежде, запустив проект локально.Dockerfile.
Следующим шагом будет создание
Dockerfile. Это специальный файл с набором инструкции по сборке Docker-образа.Создайте файл
Dockerfile без расширения со следующим содержимым:FROM python:3.11.4-buster
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code
RUN pip install --upgrade pip
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
Разберём по порядку:
-
FROM python:3.11.4-buster - В этой строке указываем на используемый при сборке базовый образ. В нашем случае это Python 3.11.4. Можно взять любую версию, включая 3.12, однако учитывайте совместимости библиотек! В нашем проекте используется Django 4.2.2, поэтому и используется Python 3.11.🔥5
-
-
-
-
-
-
-
-
-
.dockerignore файл.
По аналогии с файлом
В нашем случае не нужно, чтобы внутрь контейнера попал
В файле пропишем всего одну строку –
Копирование файлов на VPS.
Скопировать файлы проекта можно разными способами, например, воспользовавшись git (репозиторий на github или другом сервисе) или использовав SFTP.
Я воспользуюсь SFTP и программой для этого WinSCP для Windows. Для этого подойдут и другие программы, например, FileZilla, XFTP и прочие.
Опущу этот процесс, т.к. он индивидуален, и каждый сам выбирает способ доставки файлов проекта на сервер.
Сборка образа.
После того, как проект подготовлен и скопированы файлы, приступим к сборке образа.
Запуск Docker-контейнера состоит из двух этапов. Первый – сборка или использование готового образа. В нашем случае готового образа нет, поэтому его необходимо создать. Второй этап заключается в запуске контейнера с указанием параметров запуска и собранного контейнера.
Все дальнейшие действия будут производиться на VPS. Подключитесь к серверу по SSH и перейдите в директорию с проектом. Момент с подключением и работой с сервером я опущу. Если вам нужен гайд по работе с сервером, сообщите об этом в комментариях (Подписчики с Boosty имеют приоритет в просьбах на будущие посты 😉)
Для сборки образа в директории проекта выполним команду:
Разберём команду:
-
-
-
ENV PYTHONDONTWRITEBYTECODE=1 - Эта переменная окружения говорит Python не записывать файлы байт-кода (.pyc) на диск. Обычно Python автоматически компилирует исходные файлы .py в файлы байт-кода .pyc, чтобы ускорить последующий запуск программы. Однако в контейнерных окружениях это может быть нежелательно-
ENV PYTHONUNBUFFERED=1 - Эта переменная окружения отключает буферизацию вывода Python. По умолчанию Python буферизует ввод и вывод, чтобы улучшить производительность. Это значит, что вывод в терминал или лог-файлы может быть задержан до тех пор, пока буфер не заполнится. Установка этой переменной в 1 отключает буферизацию, что приводит к немедленному выводу всех данных. Это полезно в контейнерных приложениях.-
WORKDIR /code - В этой строке указываем, что рабочая директория с файлами проекта будет по пути /code относительно корневой директории файловой системы /.-
RUN pip install --upgrade pip - В этой строке выполняется команда обновления pip.-
COPY requirements.txt /code/ - В этой строке происходит копирование файла зависимостей в рабочую директорию внутри образа.-
RUN pip install -r requirements.txt - В этой строке происходит установка зависимостей в окружение Python внутри образа.-
COPY . /code/ - В этой строке копируем файлы проекта в рабочую директорию.-
EXPOSE 8000 - В этой строке указываем, что наш образ будет "вещать" на 8000-м порту.-
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] - В этой строке выполняем команду запуска веб-сервера Django, дополнительно указывая 0.0.0.0:8000, что позволяет веб-серверу вещать не только в пределах 127.0.0.1/localhost, но и быть доступным для других устройств в сети (сетевых интерфейсов)..dockerignore файл.
По аналогии с файлом
.gitignore, запрещающим добавление в индекс системы контроля версий нежелательных файлов, таких, как .env или файлов от IDE, для Docker есть такой же файл - .dockerignore.В нашем случае не нужно, чтобы внутрь контейнера попал
.env-файл, поэтому в корне проекта создадим .dockerignore-файл.В файле пропишем всего одну строку –
.env.Копирование файлов на VPS.
Скопировать файлы проекта можно разными способами, например, воспользовавшись git (репозиторий на github или другом сервисе) или использовав SFTP.
Я воспользуюсь SFTP и программой для этого WinSCP для Windows. Для этого подойдут и другие программы, например, FileZilla, XFTP и прочие.
Опущу этот процесс, т.к. он индивидуален, и каждый сам выбирает способ доставки файлов проекта на сервер.
Сборка образа.
После того, как проект подготовлен и скопированы файлы, приступим к сборке образа.
Запуск Docker-контейнера состоит из двух этапов. Первый – сборка или использование готового образа. В нашем случае готового образа нет, поэтому его необходимо создать. Второй этап заключается в запуске контейнера с указанием параметров запуска и собранного контейнера.
Все дальнейшие действия будут производиться на VPS. Подключитесь к серверу по SSH и перейдите в директорию с проектом. Момент с подключением и работой с сервером я опущу. Если вам нужен гайд по работе с сервером, сообщите об этом в комментариях (Подписчики с Boosty имеют приоритет в просьбах на будущие посты 😉)
Для сборки образа в директории проекта выполним команду:
sudo docker build -t project_image .
Разберём команду:
-
sudo docker - Вызываем Docker с правами администратора (root).-
build - Сообщаем, что нам нужно собрать образ.-
-t project_image - Присваиваем образу тег (имя), по которому будем обращаться к нему. Можно указать просто имя образа, а также дополнительно версию или другое обозначение, например, -t project_image:dev.🔥3
-
Выполняем команду. Начнётся процесс сборки. Докер пойдёт по шагам, указанным в Dockerfile, начиная со скачивания базового образа и заканчивая копированием файлов. Да, он остановится на этом, т.к. последняя строка
Запуск контейнера.
После того, как собрали образ, необходимо запустить контейнер.
Для этого выполним следующую команду:
Разберём команду:
-
-
-
-
-
-
-
Проверка работы.
После того, как контейнер создан и запущен, откройте браутер и перейдите по адресу
Должен открыться сайт.
Дополнительно.
Если сайт не открылся, стоит проверить состояние контейнера, выполнив команду:
Эта команда отобразит все контейнеры, как запущенные, так и остановленные. Найдите в списке контейнер
Если отображается
Вероятно, там будет ответ на то, почему не работает проект.
Если же контейнер указан как
Заключение.
Данный пост не описывает полноценный процесс разворачивания Django-проекта на VPS, а лишь подготовку или запуск
В одном из следующих постов мы с вами разберёмся, как запустить полноценный "prod-сервер" с базой данных и веб-сервером NGINX в Docker compose-сервисе.
Файлы к посту, можно получить в боте по коду: 687007
Пост на сайте
Поддержать проект
#Python #Docker #VPS #PostgreSQL #Django #dotenv #Dockerfile #NGINX #SFTP
. - Точка означает, что Dockerfile для сборки образа находится в этой же директории. Если у вас он в другой, можно указать путь, полный или относительный.Выполняем команду. Начнётся процесс сборки. Докер пойдёт по шагам, указанным в Dockerfile, начиная со скачивания базового образа и заканчивая копированием файлов. Да, он остановится на этом, т.к. последняя строка
CMD ... будет выполнена при запуске контейнера, а не при сборке образа.Запуск контейнера.
После того, как собрали образ, необходимо запустить контейнер.
Для этого выполним следующую команду:
sudo docker run --name project --env-file ./.env -p 8000:8000 -d project_image
Разберём команду:
-
sudo docker - Идентично предыдущему разделу.-
run - Сообщаем, что мы хотим запустить контейнер.-
--name project - Определяем имя контейнера. Если не указать, то имя будет сгенерированно случайно, но для удобства работы с контейнером его всё же стоит указывать.-
--env-file ./.env - В данном параметре мы указываем, что нужно получить переменные окружения из .env-файла для того, чтобы они были доступны внутри контейнера. При этом самого файла там не будет.-
-p 8000:8000 - В этом параметре указываем, что контейнер будет "вещать" наружу по 8000-му порту, используя внутренний 8000-й порт.-
-d - Данный ключ означает, что контейнер будет запущен в фоновом режиме. Если этот ключ не указать, то при запуске контейнера в терминале будут отображаться выводящиеся в консоль логи.-
project_image - В самом конце указываем используемый образ для запуска контейнера.Проверка работы.
После того, как контейнер создан и запущен, откройте браутер и перейдите по адресу
https://0.0.0.0:8000/, подставив вместо 0.0.0.0 IP-адрес сервера или, если у вас к серверу подключён домен, то https://ваш_домен:8000/.Должен открыться сайт.
Дополнительно.
Если сайт не открылся, стоит проверить состояние контейнера, выполнив команду:
sudo docker ps -a
Эта команда отобразит все контейнеры, как запущенные, так и остановленные. Найдите в списке контейнер
project и посмотрите на колонку "STATUS". Там должно отображаться UP ....Если отображается
Exited ..., следует проверить логи контейнера выполнив команду:sudo docker logs project
Вероятно, там будет ответ на то, почему не работает проект.
Если же контейнер указан как
UP ..., но не работает по IP, следует проверить настройки файрволла или открытые порты.Заключение.
Данный пост не описывает полноценный процесс разворачивания Django-проекта на VPS, а лишь подготовку или запуск
dev-сервера для того, чтобы проверять работу во время разработки.В одном из следующих постов мы с вами разберёмся, как запустить полноценный "prod-сервер" с базой данных и веб-сервером NGINX в Docker compose-сервисе.
Файлы к посту, можно получить в боте по коду: 687007
Пост на сайте
Поддержать проект
#Python #Docker #VPS #PostgreSQL #Django #dotenv #Dockerfile #NGINX #SFTP
🔥4
Приветствуем.
Мы запускаем новую рубрику "Вопросы и ответы".
В течение недели вы в комментариях к этому посту можете задавать различные вопросы нашей команде. Вопросы могут быть о чём угодно (в рамках разумного): о постах, о Python, о разработке в целом. Можно даже попросить нас сделать ревью вашего кода или помочь с чем-то.
Ровно через неделю мы подготовим пост с ответами на появившиеся вопросы.
Надеемся, что рубрика вам понравится и ждём от вас активности и интересных вопросов!
Мы запускаем новую рубрику "Вопросы и ответы".
В течение недели вы в комментариях к этому посту можете задавать различные вопросы нашей команде. Вопросы могут быть о чём угодно (в рамках разумного): о постах, о Python, о разработке в целом. Можно даже попросить нас сделать ревью вашего кода или помочь с чем-то.
Ровно через неделю мы подготовим пост с ответами на появившиеся вопросы.
Надеемся, что рубрика вам понравится и ждём от вас активности и интересных вопросов!
🔥3🤔1
Приветствую вас, друзья!
Вот и наступил долгожданный вечер пятницы. А это говорит о том, что пора отложить все дела и отдохнуть за просмотром очередного фильма из нашей подборки. Тащите к столу закуски и напитки, устраивайтесь поудобнее и наслаждайтесь просмотром
Фильм: Гуд бай, Ленин
Год: 2003
Мать 21-летнего Алекса всегда была настоящей, активной коммунисткой. Она тяжело заболела и впала в кому, когда ГДР еще существовала, а Берлинская стена казалась несокрушимой. Но самые большие проблемы для Алекса начались 8 месяцев спустя, когда его мать пришла в себя – уже в объединенной Германии. Ее сердце так слабо, что любое душевное волнение может закончиться для нее летальным исходом. А что может стать более убийственным для убежденной коммунистки, чем падение Берлинской стены и торжество капитализма? И тогда Алексу пришла в голову гениальная идея: построить коммунизм в одной отдельно взятой квартире…
https://www.sspoisk.ru/film/1549/
Приятного просмотра! А в данном случае ещё и приятного прослушивания: гениальный и пронзительный саундтрек от Яна Тирсена (известного также по работе над музыкой для “Амели”) – как будто самостоятельный персонаж этого фильма.
Вот и наступил долгожданный вечер пятницы. А это говорит о том, что пора отложить все дела и отдохнуть за просмотром очередного фильма из нашей подборки. Тащите к столу закуски и напитки, устраивайтесь поудобнее и наслаждайтесь просмотром
Фильм: Гуд бай, Ленин
Год: 2003
Мать 21-летнего Алекса всегда была настоящей, активной коммунисткой. Она тяжело заболела и впала в кому, когда ГДР еще существовала, а Берлинская стена казалась несокрушимой. Но самые большие проблемы для Алекса начались 8 месяцев спустя, когда его мать пришла в себя – уже в объединенной Германии. Ее сердце так слабо, что любое душевное волнение может закончиться для нее летальным исходом. А что может стать более убийственным для убежденной коммунистки, чем падение Берлинской стены и торжество капитализма? И тогда Алексу пришла в голову гениальная идея: построить коммунизм в одной отдельно взятой квартире…
https://www.sspoisk.ru/film/1549/
Приятного просмотра! А в данном случае ещё и приятного прослушивания: гениальный и пронзительный саундтрек от Яна Тирсена (известного также по работе над музыкой для “Амели”) – как будто самостоятельный персонаж этого фильма.
🔥4
Что выведет код с изображения ниже? №25
Anonymous Quiz
15%
[1, 3, 1, 0, 4, 2, 2, 4, 1, 3, 1, 0]
0%
[1, 3, 1, 0, 4, 2, 2, 4, 1, 3, 1, 0, 1, 0, 1, 0]
10%
[1, 3, 1.0, 0.3, 4, 2, 2.0, 4.0, 1, 3, 1.0, 0.3]
10%
[1, 3, 1.0, 0.3, 4, 2, 2.0, 4.0, 1, 3, 1.0, 0.3, 1.0, 0.3, 1.0, 3.3 ]
25%
ZeroDivisionError
40%
Нет правильного ответа
🔥3👍1
Вчера мы опубликовали весьма хитрую задачу. Правильно ответили 33%, но удивительно не это, а то, что ожидаемый нами вариант "верного ответа" никто не выбрал...
Код задачи:
Разбор задачи
Вы, наверное, задаётесь вопросом, почему верный ответ заключался в том, что правильного варианта не было в списке? Всё дело в устройстве задачи и в том, как работают списки в цикле
У нас уже были подобные задачи: №6 и №9, но они немного другие.
Создаём функцию
Внутри функции проходимся циклом
После цикла возвращаем список.
После описания функции вызываем
Правильный ответ
И кто-то из вас наверняка спросит: "Но как же так? Я посчитал, всё сопоставил, и верный ответ -
Дело в том, что правильного ответа нет в списке, потому что вывода не будет. Программа запустится, начнёт работу, но никогда не дойдёт до вывода результата.
Главный подвох
Главный подвох заключается в том, что при первом вызове
Когда в первый раз вызывается
- Сначала список
- На первой итерации цикла
- На второй итерации,
Так как новые элементы постоянно добавляются в список, цикл
Итог
Всё остальное в задаче служит для отвлечения внимания. Вот такая вот хитрая задача была вчера.
Код задачи:
def my_func(num, lst=[1, 3]):
for i in lst:
lst.append(round(num / i, 1))
return lst
print(my_func(1) + my_func(8, [4, 2]) + my_func(1))
Разбор задачи
Вы, наверное, задаётесь вопросом, почему верный ответ заключался в том, что правильного варианта не было в списке? Всё дело в устройстве задачи и в том, как работают списки в цикле
for в Python.У нас уже были подобные задачи: №6 и №9, но они немного другие.
Создаём функцию
my_func, принимающую два аргумента: num и lst. Для аргумента lst устанавливаем значение по умолчанию [1, 3].Внутри функции проходимся циклом
for по списку lst. В теле цикла добавляем в список новый элемент - округлённый функцией round() до одного символа после запятой результат деления числа num на текущее число i из списка.После цикла возвращаем список.
После описания функции вызываем
print(), в котором складываем три списка, полученных в результате вызова функции my_func с разными аргументами.Правильный ответ
И кто-то из вас наверняка спросит: "Но как же так? Я посчитал, всё сопоставил, и верный ответ -
[1, 3, 1.0, 0.3, 4, 2, 2.0, 4.0, 1, 3, 1.0, 0.3, 1.0, 0.3, 1.0, 3.3]!"Дело в том, что правильного ответа нет в списке, потому что вывода не будет. Программа запустится, начнёт работу, но никогда не дойдёт до вывода результата.
Главный подвох
Главный подвох заключается в том, что при первом вызове
my_func(1) запускается цикл с дефолтным значением lst=[1, 3]. Особенность цикла for заключается в том, что итерация идёт по списку "от начала и до конца", пока есть элементы - цикл будет продолжаться. А так как мы каждый раз добавляем в конец списка новый элемент, цикл будет длиться, пока не переполнится память или выполнение кода не будет остановлено.Когда в первый раз вызывается
my_func(1), происходит следующее:- Сначала список
lst содержит [1, 3].- На первой итерации цикла
for, i равно 1, и в конец списка добавляется round(1 / 1, 1) или 1.0. Теперь список lst равен [1, 3, 1.0].- На второй итерации,
i равно 3, и добавляется round(1 / 3, 1) или 0.3. Теперь список равен [1, 3, 1.0, 0.3].Так как новые элементы постоянно добавляются в список, цикл
for никогда не завершится. Это приводит к бесконечному циклу.Итог
Всё остальное в задаче служит для отвлечения внимания. Вот такая вот хитрая задача была вчера.
🔥3👍1👎1🤔1🤯1😱1
Tips & Tricks. №1
Полезные горячие клавиши в PyCharm.
Горячие клавиши в PyCharm значительно ускоряют процесс разработки, делая его более эффективным и приятным. Вот подборка полезных горячих клавиш, которые пригодятся при повседневной работе:
-
-
-
-
-
Указанные горячие клавиши позволяют управлять процессом разработки и ускоряют взаимодействие с кодом.
P.S. Данные горячие клавиши также работают и в других продуктах JetBrains, например, в Intellij Idea, Android Studio или WebStorm.
Полезные горячие клавиши в PyCharm.
Горячие клавиши в PyCharm значительно ускоряют процесс разработки, делая его более эффективным и приятным. Вот подборка полезных горячих клавиш, которые пригодятся при повседневной работе:
-
CTRL + D - Создаёт дубликат строки на которой находится курсор или нескольких выделенных строк. Пригодится при создании однотипных команд с разными данными.-
SHIFT + SHIFT - Двойное нажатие клавиши SHIFT вызывает диалоговое окно быстрого поиска по содержимому в файлах проекта. Полезно, когда надо найти кусочек кода в проекте, но не помнишь, в каком файле он находится.-
CTRL + SPACE - Подсветка доступных методов и функций, автодоплнение названия и другие действия с объектом (функцией, переменной, классом).-
ALT + ENTER - Вызов контекстного меню, например, для быстрого импорта или других действий, указываемых в желтой лампочке. Полезно при написании без использования курсора мыши. Повышает скорость печати и действий.-
SHIFT + F10 - Запуск текущего открытого .py-файла или указанной конфигурации.Указанные горячие клавиши позволяют управлять процессом разработки и ускоряют взаимодействие с кодом.
P.S. Данные горячие клавиши также работают и в других продуктах JetBrains, например, в Intellij Idea, Android Studio или WebStorm.
🔥6❤1👍1
Найдите ошибку в коде ниже и исчерпывающим образом объясните ее в комментариях.
#python #код_на_салфетке #найди_ошибку
#python #код_на_салфетке #найди_ошибку
🤔1
Вторая задача получилась совсем коротенькой, но интересной. В задаче была не одна, а целых две ошибки.
Код задачи:
Первая ошибка.
Самая очевидная и бросающаяся в глаза – пробел между
Объяснения тут, пожалуй, излишни. Python хоть и славится своим простым синтаксисом, но это не значит, что его стоит нарушать. Лишние отступы, разделители – всё это ему не понравится, и он будет ругаться в терминале трейсбэками.
Вторая ошибка.
Вторая ошибка куда серьезнее и не такая очевидная. Её нашёл Elshad, не без помощи GPT🤫.
Находится она в определении
Однако в случае с
Как это обойти?
Самый простой способ – воспользоваться методом
P.S. В разборе намеренно допущена одна ошибка, которая вовсе и не ошибка... Найдёте её?)
#python #код_на_салфетке #найди_ошибку #разбор_ошибки
Код задачи:
text = "идёт", "по", "плану"
print (f"Всё {*text}")
Первая ошибка.
Самая очевидная и бросающаяся в глаза – пробел между
print и (). Указал на ошибку в комментариях - Александр Бабичев. Объяснения тут, пожалуй, излишни. Python хоть и славится своим простым синтаксисом, но это не значит, что его стоит нарушать. Лишние отступы, разделители – всё это ему не понравится, и он будет ругаться в терминале трейсбэками.
Вторая ошибка.
Вторая ошибка куда серьезнее и не такая очевидная. Её нашёл Elshad, не без помощи GPT🤫.
Находится она в определении
f-строки: f"Всё {*text}". Дело в том, что в переменную text записана коллекция, а точнее – кортеж. Кортежи, списки и прочие коллекции можно "распаковывать", получая элементы оттуда, например:lst = [1, 'a', '23']
print(*lst)
>>>1 a 23
Однако в случае с
f-строками такое не пройдёт. Там попросту запрещены любые "звёздные выражения" (starred expression). f-строки предназначены для встроенной интерполяции. Внутрь {} можно передать только один аргумент, который будет преобразован к строке, в то время как *-выражения, или попросту распаковка списка, возвращает каждый элемент списка как отдельный аргумент. Как это обойти?
Самый простой способ – воспользоваться методом
.join у объекта строки. Метод получает в качестве аргумента объект коллекции, затем проходит по нему циклом и возвращает сконкатенированную строку. В ней разделителем будет объект строки, у которого и вызывался метод. Например:text = "идёт", "по", "плану"
print(f"Всё {" ".join(text)}")
P.S. В разборе намеренно допущена одна ошибка, которая вовсе и не ошибка... Найдёте её?)
#python #код_на_салфетке #найди_ошибку #разбор_ошибки
👍4🤔1
Telegram
Бот на салфетке
Бот-помощник для Telegram-канала "Код на салфетке"
Канал: https://t.iss.one/press_any_button
Вопросы и предложения @proDreams
Канал: https://t.iss.one/press_any_button
Вопросы и предложения @proDreams
Приветствуем!
Для всех, кто давно хотел нас поддержать, но стеснялся или не знал, как, сегодня прекрасные новости! Сделать пожертвование теперь можно через нашего бота, используя новый способ оплаты Telegram Stars. А завтра расскажем, как мы осуществили это технически.
Ссылка на бота: https://t.iss.one/press_any_button_bot?start=donate
Открыть меню поддержки можно вызвав команду:
Для всех, кто давно хотел нас поддержать, но стеснялся или не знал, как, сегодня прекрасные новости! Сделать пожертвование теперь можно через нашего бота, используя новый способ оплаты Telegram Stars. А завтра расскажем, как мы осуществили это технически.
Ссылка на бота: https://t.iss.one/press_any_button_bot?start=donate
Открыть меню поддержки можно вызвав команду:
/donate🔥5❤2
AIOgram3 18. Подключаем оплату Telegram Stars
Автор: Иван Ашихмин
6 июня Павел Дуров сообщил, что в Telegram вводится новая валюта — Stars. Stars позволят производить покупку цифровых товаров и услуг, проще говоря, оплачивать покупки внутри Telegram, например, в ботах или в MiniApps. Однако не всё так радужно. Введение нового способа оплаты влечёт за собой отключение всех остальных платёжных средств. Если ваш бот принимал оплату через ЮКассу, то теперь только "Звёзды". Причины таких изменений оставим за скобками и сосредоточимся на более важных вещах, а именно на том, как внедрить в Telegram-бота новый способ оплаты — Telegram Stars.
Приобрести звёзды можно, открыв настройки Telegram и найдя пункт "Звёзды Telegram".
Стоит отметить.
Автор: Иван Ашихмин
6 июня Павел Дуров сообщил, что в Telegram вводится новая валюта — Stars. Stars позволят производить покупку цифровых товаров и услуг, проще говоря, оплачивать покупки внутри Telegram, например, в ботах или в MiniApps. Однако не всё так радужно. Введение нового способа оплаты влечёт за собой отключение всех остальных платёжных средств. Если ваш бот принимал оплату через ЮКассу, то теперь только "Звёзды". Причины таких изменений оставим за скобками и сосредоточимся на более важных вещах, а именно на том, как внедрить в Telegram-бота новый способ оплаты — Telegram Stars.
Приобрести звёзды можно, открыв настройки Telegram и найдя пункт "Звёзды Telegram".
Стоит отметить.
1🔥9
На момент написания не было актуальной информаций по тому, как и где использовать полученные от пользователей звёзды. Статья будет дополняться по мере обновления информации от Telegram. Если вам что-то известно, сообщите нам!
Обновление зависимостей.
Для полноценной поддержки нового способа оплаты требуется версия AIOgram 3.7.0. Для обновления библиотеки достаточно выполнить команду:
После этого обновите версию в файле
Кнопка оплаты.
Перед тем, как мы начнём писать обработчик команды, выставляющей счёт на оплату, необходимо создать кнопку для оплаты, нажатие на которую откроет окно для оплаты.
В пакете
Пропишем функцию
В теле функции создадим переменную
В него можно передать список списков с объектами класса кнопки, но это не совсем удобно, проще пользоваться методами класса. На следующей строке вызываем у объекта класса метод
-
-
Далее делаем возврат переменной
Код файла:
Создание клавиатуры не обязательно, отправлять счёт можно и без неё. Однако, она позволяет настроить текст кнопки, а также добавить дополнительные функциональные кнопки, такие, как отмена платежа, выбор другого товара и т.д.
Обработчик выставления счёта.
Приступим к написанию обработчика команды.
В пакете
В этом файле пропишем асинхронную функцию
Создадим переменную
-
-
Далее у переменной
-
-
-
-
-
-
-
Код обработчика:
Обновление зависимостей.
Для полноценной поддержки нового способа оплаты требуется версия AIOgram 3.7.0. Для обновления библиотеки достаточно выполнить команду:
pip install -U aiogram
После этого обновите версию в файле
requirements.txt.aiogram3.7.0
Кнопка оплаты.
Перед тем, как мы начнём писать обработчик команды, выставляющей счёт на оплату, необходимо создать кнопку для оплаты, нажатие на которую откроет окно для оплаты.
В пакете
botlogic создадим новый пакет keyboards, а в нём файл payment_keyboard.py.Пропишем функцию
payment_keyboard, которая ничего не принимает.В теле функции создадим переменную
builder, в которой определим экземпляр класса InlineKeyboardBuilder.В него можно передать список списков с объектами класса кнопки, но это не совсем удобно, проще пользоваться методами класса. На следующей строке вызываем у объекта класса метод
.button, добавляющий кнопку в сборщик клавиатуры. Передаём два аргумента:-
text — Определяет текст на кнопке. Если в тексте будет XTR или эмодзи звезды ⭐️, оно автоматически заменится на иконку Telegram Stars.-
pay — Определяет тип кнопки как кнопку для оплаты.Далее делаем возврат переменной
builder, применив к ней метод .as_markup, чтобы получить объект готовой к размещению в сообщении клавиатуры.Код файла:
from aiogram.utils.keyboard import InlineKeyboardBuilder
def payment_keyboard():
builder = InlineKeyboardBuilder()
builder.button(text=f"Оплатить 20 ⭐️", pay=True)
return builder.as_markup()
Создание клавиатуры не обязательно, отправлять счёт можно и без неё. Однако, она позволяет настроить текст кнопки, а также добавить дополнительные функциональные кнопки, такие, как отмена платежа, выбор другого товара и т.д.
Обработчик выставления счёта.
Приступим к написанию обработчика команды.
В пакете
handlers создадим файл payment.py.В этом файле пропишем асинхронную функцию
send_invoice_handler, принимающую message — объект класса Message.Создадим переменную
prices, в которую поместим список с объектами класса LabeledPrice, вернее, с одним объектом, так как для оплаты через Telegram Stars этот список должен состоять из одного элемента. В объект класса передаём следующие аргументы:-
label — Определение валюты. В нашем случае это XTR.-
amount — Стоимость в звёздах.Далее у переменной
message вызываем метод .answer_invoice, чтобы бот ответил на сообщение пользователя кнопкой со счётом на оплату. В метод передаём следующие аргументы:-
title — Название платежа, товара или услуги.-
description — Описание платежа, товара или услуги.-
prices — Список объектов LabeledPrice, определённый ранее в одноимённой переменной.-
provider_token — Токен платёжной системы, для Telegram Stars просто отправляем пустую строку.-
payload — Маркировка платежа. Она не отображается пользователю, а может использоваться для разделения платежей по их типам и так далее. Максимум 128 байт данных (в Python один символ занимает один байт, но стоит учитывать, что специальные символы или эмодзи могут занимать больше места).-
currency — Валюта платежа, для Telegram Stars это XTR.-
reply_markup — Объект клавиатуры.Код обработчика:
🔥6
from aiogram.types import LabeledPrice, Message
from botlogic.keyboards.payment_keyboard import payment_keyboard
async def send_invoice_handler(message: Message):
prices = [LabeledPrice(label="XTR", amount=20)]
await message.answer_invoice(
title="Поддержка канала",
description="Поддержать канал на 20 звёзд!",
prices=prices,
provider_token="",
payload="channel_support",
currency="XTR",
reply_markup=payment_keyboard(),
)
Предпродажная проверка.
Счёт выставлен, пользователь нажимает "Оплатить". Если у него не хватает звёзд, система предложит их приобрести. Если звёзд у него хватает, он произведёт оплату, и в этот момент Telegram пришлёт в бота запрос "точно ли всё хорошо?". На ответ у нас будет ровно 10 секунд. Если мы по каким-то причинам не хотим принимать оплаты у данного пользователя или логика бота настроена на отмену платежа, в таком случае необходимо дать ответ, сигнализирующий об отмене платежа, сопроводив его причиной отмены. В противном же случае, подтверждаем, что всё "Ок".
В этом же файле создадим асинхронную функцию
pre_checkout_handler, принимающую аргумент pre_checkout_query — объект класса PreCheckoutQuery.В теле функции у переменной
pre_checkout_query вызываем метод .answer, передавая в него аргумент ok со значением True.Код функции:
from aiogram.types import PreCheckoutQuery
async def pre_checkout_handler(pre_checkout_query: PreCheckoutQuery):
await pre_checkout_query.answer(ok=True)
Информирование о покупке.
Бюрократия позади, осталось только поздравить пользователя с покупкой!
В этом же файле создадим асинхронную функцию
success_payment_handler, принимающую аргумент message — объект класса Message.В объекте класса
Message хранится различная информация о текущем сообщении, а в поле successful_payment находится информация о платеже, такая, как идентификатор платежа, сумма, валюта, информация, полученная от пользователя. По-хорошему, это всё необходимо сохранить во избежание возможных вопросов по платежам в будущем.В теле функции делаем обычный ответ, сообщая, что покупка прошла успешно.
Код функции:
async def success_payment_handler(message: Message):
await message.answer(text="🥳Спасибо за вашу поддержку!🤗")
Команда paysupport и немного про возврат средств.
Telegram также предъявляет условия к возврату средств пользователям. Не за все товары и услуги подразумевается возврат средств, однако у пользователя всё равно должна быть возможность запросить возврат средств, либо быть проинформированным касательно этого.
Для информирования пользователя обязательно должна быть команда
/paysupport. В ней можно указать условия возврата, контактные данные и др. Давайте сделаем эту команду.Создадим асинхронную функцию
pay_support_handler, принимающую message — объект класса Message. В теле функции пропишем ответ на сообщение с текстом, описывающим условия для возврата средств.Код функции:
async def pay_support_handler(message: Message):
await message.answer(
text="Добровольные пожертвования не подразумевают возврат средств, "
"однако, если вы очень хотите вернуть средства - свяжитесь с нами." )
Непосредственно возврат средств можно сделать доступным пользователю. Для этого необходимо создать обработчик команды возврата, в котором, обращаясь к методу
.refund_star_payment у объекта Bot, передать в него user_id и telegram_payment_charge_id.🔥4
-
-
Регистрация обработчиков.
Всё готово, осталось зарегистрировать обработчики в
Откроем файл
-
-
-
-
Тестирование.
Запустим бота и выполним команду
Получим сообщение с информацией о платеже и кнопкой-счётом. Нажмём на кнопку.
Откроется окно с подтверждением оплаты (если у вас нет звёзд — откроется окно приобретения, как на первом скриншоте в начале поста). Нажимаем "Подтвердить и заплатить".
В чате выстрелит конфетти, и мы увидим сообщение об успешном платеже.
Заключение.
Нововведение, конечно, всех удивило и немного застало врасплох. На переход дали мало времени, и наверняка не все даже узнали об этом. Интересно будет посмотреть, к чему всё это приведёт.
Файлы к посту, можно получить в боте по коду: 236204
Пост на сайте
Поддержать проект на Boosty
Поддержать проект в Telegram
#Python #AIOgram #Telegram_бот #Код_на_салфетке #Telegram_Stars #Оплата_в_Telegram
user_id — Telegram-ID пользователя, запрашивающего возврат средств.-
telegram_payment_charge_id — Идентификатор платежа, совершённого пользователем.Регистрация обработчиков.
Всё готово, осталось зарегистрировать обработчики в
main.py.Откроем файл
main.py и в функции start добавим четыре регистрации:-
send_invoice_handler — Регистрируем как обычное сообщение, указав фильтр команды donate.-
pre_checkout_handler — Регистрируем как событие pre_checkout_query.-
success_payment_handler — Регистрируем как обычное сообщение. В качестве фильтра используем так называемый "Магический фильтр F", представляющий собой объект Message. В фильтре обращаемся к полю successful_payment. Если оно не пустое (успешная оплата), будет вызван обработчик.-
pay_support_handler — Регистрируем как обычное сообщение с фильтром на команду paysupport.from aiogram import F
dp.message.register(payment.send_invoice_handler, Command(commands="donate"))
dp.pre_checkout_query.register(payment.pre_checkout_handler)
dp.message.register(payment.success_payment_handler, F.successful_payment)
dp.message.register(payment.pay_support_handler, Command(commands="paysupport"))
Тестирование.
Запустим бота и выполним команду
/donate.Получим сообщение с информацией о платеже и кнопкой-счётом. Нажмём на кнопку.
Откроется окно с подтверждением оплаты (если у вас нет звёзд — откроется окно приобретения, как на первом скриншоте в начале поста). Нажимаем "Подтвердить и заплатить".
В чате выстрелит конфетти, и мы увидим сообщение об успешном платеже.
Заключение.
Нововведение, конечно, всех удивило и немного застало врасплох. На переход дали мало времени, и наверняка не все даже узнали об этом. Интересно будет посмотреть, к чему всё это приведёт.
Файлы к посту, можно получить в боте по коду: 236204
Пост на сайте
Поддержать проект на Boosty
Поддержать проект в Telegram
#Python #AIOgram #Telegram_бот #Код_на_салфетке #Telegram_Stars #Оплата_в_Telegram
🔥6
Приветствуем.
В прошлую пятницу мы опубликовали пост, в котором попросили вас задавать нам вопросы.
Было всего три вопроса: Первый в комментариях к посту, второй в нашем чате, а третий прилетел в личные сообщения.
Чтож, давайте на них ответим!
Ревью бота.
Ссылка на сообщение: https://t.iss.one/press_any_button/685?comment=95471
Начнём с того, что сразу бросилось в глаза:
-
-
-
-
- Миграции - Для управления БД удобнее использовать инструменты миграции, такие как
В целом интересный бот. Хотелось бы запустить и протестировать некоторые улучшения для него, но он не запустился😂. Отправил автору сообщения свои мысли по улучшению некоторых моментов.
Статистика.
На канале 516 подписчиков и около 100 просмотров за сутки. Что, вполне себе неплохо (а хотелось бы больше!). По сайту тоже всё хорошо, дошли уже примерно до 100-120 ежедневных уникальных посетителей. Вот наверное всё, что можно ответить по этому поводу.
Где начинать разработку?
Не совсем понятно, что значит "начинать разработку сразу на сервере". Начинать её в любом случае проще локально, так как это позволит быстрее написать основу, продумать структуру и всё отладить, запуская проект. Потом, когда придёт пора деплоя, уже можно перебираться в разработку на сервере. Сделать это можно используя VS Code или, если у вас мощный сервер PyCharm, подключаясь по SSH и ведя удалённую разработку с доступом к консоли, докеру и прочему. Однако, лично мне удобнее всё ещё работу вести локально, затем просто по SFTP подкидывать изменённые файлы и в терминале перезапускать.
В прошлую пятницу мы опубликовали пост, в котором попросили вас задавать нам вопросы.
Было всего три вопроса: Первый в комментариях к посту, второй в нашем чате, а третий прилетел в личные сообщения.
Чтож, давайте на них ответим!
Ревью бота.
Ссылка на сообщение: https://t.iss.one/press_any_button/685?comment=95471
Начнём с того, что сразу бросилось в глаза:
-
README.md - Это же лицо проекта в репозитории, а такое скудненькое. Опиши, что делает, какие технологии используются, какие планы по реализации и оформи инструкцию по запуску.-
.env - Где он? Без примера .env не понятно какие переменные нужны.-
requirements.txt - По всей видимости собран используя pip freeze? Много лишнего в нём, что так и так установится с нужными пакетами + это может привести к проблемам, условно, обновишь ты версию AIOgram, а всё остальное оставишь как прежде, айограм установится, обновит зависимости, а они потом обратно откатятся, т.к. прописаны более старые версии. При этом в нём есть не всё, что нужно для работы бота.-
load_dotenv - Вместо получения сырых данных из .env, как по мне, лучше использовать pydantic для валидации, а именно pydantic-settings, но это больше вкусовщина.- Миграции - Для управления БД удобнее использовать инструменты миграции, такие как
Alembic. Можно контролировать изменения и откатываться при необходимости.В целом интересный бот. Хотелось бы запустить и протестировать некоторые улучшения для него, но он не запустился😂. Отправил автору сообщения свои мысли по улучшению некоторых моментов.
Статистика.
Ты давно статистикой не делился. Не помню, где это было в последний раз и когда. Есть рост? Положительный ))
На канале 516 подписчиков и около 100 просмотров за сутки. Что, вполне себе неплохо (а хотелось бы больше!). По сайту тоже всё хорошо, дошли уже примерно до 100-120 ежедневных уникальных посетителей. Вот наверное всё, что можно ответить по этому поводу.
Где начинать разработку?
Лучше начать разработку на локальном компе или на реал серваке?
Не совсем понятно, что значит "начинать разработку сразу на сервере". Начинать её в любом случае проще локально, так как это позволит быстрее написать основу, продумать структуру и всё отладить, запуская проект. Потом, когда придёт пора деплоя, уже можно перебираться в разработку на сервере. Сделать это можно используя VS Code или, если у вас мощный сервер PyCharm, подключаясь по SSH и ведя удалённую разработку с доступом к консоли, докеру и прочему. Однако, лично мне удобнее всё ещё работу вести локально, затем просто по SFTP подкидывать изменённые файлы и в терминале перезапускать.
🔥3👍2
Приветствую, дорогие друзья!
Наконец-то пятница! Скажут те, у кого пятидневная рабочая неделя)). Настало время, когда мы можем позволить себе расслабиться, забыть о повседневных заботах и просто наслаждаться просмотром кино.
Фильм: Атлас
Год: 2024
События фильма разворачиваются в не столь отдалённом будущем, в котором искусственный интеллект захватил власть над людьми и развязал войну на уничтожение всего человечества. Женщина присоединяется к миссии по поимке робота-отступника, с которым её связывает загадочное прошлое. Но всё идёт не по плану, и чтобы не потерять единственный шанс спасти мир от искусственного интеллекта, Атлас должна довериться ему.
https://www.sspoisk.ru/film/4477073/
Приятного просмотра!
Наконец-то пятница! Скажут те, у кого пятидневная рабочая неделя)). Настало время, когда мы можем позволить себе расслабиться, забыть о повседневных заботах и просто наслаждаться просмотром кино.
Фильм: Атлас
Год: 2024
События фильма разворачиваются в не столь отдалённом будущем, в котором искусственный интеллект захватил власть над людьми и развязал войну на уничтожение всего человечества. Женщина присоединяется к миссии по поимке робота-отступника, с которым её связывает загадочное прошлое. Но всё идёт не по плану, и чтобы не потерять единственный шанс спасти мир от искусственного интеллекта, Атлас должна довериться ему.
https://www.sspoisk.ru/film/4477073/
Приятного просмотра!
🔥3
Приветствуем!
Мы продолжаем попытки завоевать медиа-пространство. Сперва это были три стрима (к которым хорошо бы вернуться, но пока нет идей), а теперь это короткие видео YouTube Shorts.
Посмотреть первое видео можно по ссылке: https://www.youtube.com/shorts/AcBJriDXwQo
Будем очень благодарны, если вы поставите лайк и оставите комментарий. Это позволит алгоритмам ютуба понять, что видео интересно и будет предлагать его другим зрителям.
Оставляйте ваши отзывы, мы всё прочтём и учтём в следующем видео! Так может и до больших гайдов не далеко?😉
Мы продолжаем попытки завоевать медиа-пространство. Сперва это были три стрима (к которым хорошо бы вернуться, но пока нет идей), а теперь это короткие видео YouTube Shorts.
Посмотреть первое видео можно по ссылке: https://www.youtube.com/shorts/AcBJriDXwQo
Будем очень благодарны, если вы поставите лайк и оставите комментарий. Это позволит алгоритмам ютуба понять, что видео интересно и будет предлагать его другим зрителям.
Оставляйте ваши отзывы, мы всё прочтём и учтём в следующем видео! Так может и до больших гайдов не далеко?😉
🔥5