Легкий путь в Python
5.1K subscribers
97 photos
18 videos
3 files
155 links
Я — Алексей Яковенко, опытный разработчик Python. Здесь вы найдете статьи, заметки, посты и видео для прокачки навыков программирования 🐍 Интересное найдет и новичок, и профи 💡

📬По вопросам: https://t.me/yakvenalexx
🗣Сообщество: https://vk.cc/cxKNTb
Download Telegram
Возможно опубликую раньше чем в четверг)
👍13🔥93😁1
Друзья, приветствую! 🌟 Обещанная статья уже опубликована на Хабре! В ней я рассказал о создании полноценного мини-блога с использованием Python-фреймворка FastAPI и SQLAlchemy 2.0. 📚

Что вас ждет в статье:

💎 Стек технологий: Мы используем FastAPI, SQLAlchemy с асинхронной поддержкой через aiosqlite, Alembic для миграций и другие инструменты.
💎 Функционал проекта: В блоге пользователи смогут регистрироваться и авторизовываться с помощью JWT-токенов. Мы создадим API для управления публикациями: добавление новых постов, изменение их статуса (опубликовано или черновик), а также возможность получения информации о блогах. Все это будет удобно визуализировано с помощью HTML, CSS и JS!
💎 Markdown: Блог будет автоматически оформлять тексты в формате Markdown, что позволит легко создавать красивые и структурированные посты. 📝

Если вы хотите увидеть весь процесс разработки шаг за шагом и получить полезные советы по использованию FastAPI и SQLAlchemy, обязательно загляните в статью!

🔗 Ссылка на работающий проект, документацию, статью и исходный код проекта закреплены ниже. Не упустите возможность узнать что-то новое и вдохновиться на создание собственного блога! 🚀

🔗 Ссылка на статью: Создание блога на FastAPI с нуля: JWT, Markdown и современный веб-дизайн

🔗 Проект на GitHub

🔗 Ссылка на работающий блог

🔗 Документация
Please open Telegram to view this post
VIEW IN TELEGRAM
37🔥18👍10❤‍🔥3
🚀 Друзья, у меня новая идея для статьи!

Давно хотел рассказать вам о том, как работать с FastAPI в сочетании с технологиями Celery (для фоновых задач) и Redis (для кэширования страниц и в качестве брокера для Celery). Следующую статью хочу посвятить этим темам, и чтобы не было скучно, сразу реализуем практический проект. 😉

Итак, идея следующая:

Сервис обмена файлами
Описание: Пользователь загружает файл, а приложение генерирует временную ссылку для скачивания. Ссылка активна определённое время (возможно, с ограничением на вес файла или формат).

Функционал:

📂 Загрузка файла через API и форму на сайте

🔗 Генерация временной ссылки для скачивания

🗂 Хранение ссылок и данных о файлах в Redis с TTL (время жизни)

🧹 Удаление файла после истечения времени ссылки с помощью Celery

🎁 Бонусом расскажу про классную библиотеку для FastApi для простого кэширования страниц (не зря же будем Redis поднимать)

Стек технологий:

💎 FastAPI: Обработка загрузки и скачивания файлов
💎 Redis: Хранение данных о временных ссылках
💎 Celery: Удаление файлов по истечении времени

Что скажете? 🎉
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥85👍96😍3
🚀 Регистрация на моем личном сайте теперь доступна каждому!

Как зарегистрироваться? Легче не бывает:

🤖 Зайдите в моего телеграм-бота: @yakvenalex_baseBOT
👆 Нажмите кнопку "Зарегистрироваться"
🔄 Бот автоматически создаст ваш аккаунт
🔑 После этого вы получите логин и пароль для входа на сайт

Теперь вы сможете оставлять комментарии на сайте. Более того, в ближайшее время я планирую выпустить несколько эксклюзивных публикаций, доступных только для зарегистрированных пользователей!

Благодаря системе ролей на yakvenalex.ru, авторизованные пользователи смогут получать доступ к уникальному контенту.

🤔 Хотите узнать, как устроен этот бот и какие у него возможности?

📝 Оставьте комментарий, если интересно заглянуть за кулисы проекта yakvenalex.ru и узнать о технических деталях его работы!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥174👍3🤔1
Если вы работали с Excel через Python, то могли столкнуться с ситуацией, что формат xls не поддерживается. 📊 Например, Openpyxl работает только с xlsx. В таком случае нам ничего не мешает написать собственный конвертер в пару строк кода. 🛠

Во-первых, нам понадобятся для этой задачи 2 легковесные библиотеки: pyexcel_xls и pyexcel_xlsx. Устанавливаем. 📚

Далее выполняем импорты:
from pyexcel_xls import get_data
from pyexcel_xlsx import save_data
import os


Теперь напишем простую функцию для конвертации из xls в xlsx:

def convert_xls_to_xlsx(xls_path):
# Получаем имя файла без расширения
file_name = os.path.splitext(xls_path)[0]
xlsx_path = file_name + '.xlsx'

# Читаем данные из .xls файла
xls_data = get_data(xls_path)

# Сохраняем данные в .xlsx формате
save_data(xlsx_path, xls_data)

return xlsx_path

Далее можно использовать ее в таком формате:
if file_path.endswith('.xls'):
print("Конвертация .xls в .xlsx...")
file_path = convert_xls_to_xlsx(file_path)
print(f"Файл сконвертирован: {file_path}")

Например, как часть более сложной функции с тем же openpyxl.

P.S. Бота пишу сейчас. Это кусок с реальной практики. Решил, может кому полезно будет) 🤖💡
👍32🔥7❤‍🔥41
🖥 Превращаем командную строку Windows в мощный инструмент!

Хотите улучшить свой опыт работы с терминалом в Windows? Я написал статью о том, как за пару минут превратить обычную командную строку в продвинутый инструмент с крутыми возможностями:

➡️Табы (вкладки терминалов)
➡️Переименование табов
➡️Разделение экрана на несколько частей
➡️Поддержка команд Linux и macOS
➡️SSH из коробки и многое другое!

Полное руководство по настройке ConEmu и Git для создания идеальной среды разработки.

🔗 Читать статью
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍83🤔1
This media is not supported in your browser
VIEW IN TELEGRAM
🚀 Друзья, доброе утро! Спешу поделиться отличной новостью!

🎉 Учебный проект, о котором я рассказывал пару дней назад, успешно завершен!

📁 Представляю вам файлообменник с временным хранилищем на сервере.

Вот как он работает:

1️⃣ Выбираете файл
2️⃣ Указываете срок хранения (от 1 минуты до 24 часов)
3️⃣ Получаете две ссылки: для sharing и для удаления файла

🔄 Когда вы нажимаете "Отправить", FastAPI через Redis отправляет задачу Celery. Задача? Удалить файл по истечении срока!

🧠 Изюминка проекта: FastAPI и Celery - два независимых приложения, общающихся только через Redis.

📝 Подробности о технической части ждите в моей новой статье на Хабре!

👀 А пока можете:

🔗 Посмотреть проект в действии

🔗 Изучить код FastAPI приложения

🔗 Заглянуть в код Celery приложения

🌸 Бонус: в приложенном видео вы увидите работу приложения и функционал Celery в режиме Flower.

💡 Остались вопросы? Задавайте в комментариях!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥42👍75😍3❤‍🔥1🥰1
Осталось вычитать, так что ждите, скорее всего, в субботу утром.
👍19❤‍🔥8🔥7
💡 Как узнать информацию о Telegram-боте, имея только его токен? 🤖

Иногда в процессе работы с ботами бывает, что единственное, что у вас осталось от старого проекта, — это токен. И тогда возникает вопрос: как узнать информацию о боте, чтобы восстановить его данные?

📌 Есть простой способ:

1️⃣ Откройте в браузере следующую ссылку, заменив {BOT_TOKEN} на ваш токен:

https://api.telegram.org/botBOT_TOKEN/getMe  


2️⃣ Вы получите JSON-ответ с данными бота, который выглядит так:
{
"ok": true,
"result": {
"id": 929198812,
"is_bot": true,
"first_name": "my_test",
"username": "my_test_bot",
"can_join_groups": true,
"can_read_all_group_messages": false,
"supports_inline_queries": false,
"can_connect_to_business": false,
"has_main_web_app": false
}
}


📋 В ответе содержится:

- 🆔 ID бота
- 👤 Имя (first_name)
- 🔗 Логин (username)
- 🤝 Возможности бота: участие в группах, поддержка inline-запросов и т.д.

⚠️ Совет: всегда сохраняйте информацию о боте (токен, ID, логин) в безопасном месте, чтобы в будущем не сталкиваться с такими сложностями. 🔐

Теперь вы знаете, как легко восстановить данные о боте, имея только токен! 🚀
👍207🔥6
📚 Лайфхак для FastAPI: Автоматическая загрузка файлов! 🚀

Привет, друзья! 👋 Сегодня хочу поделиться крутым приемом из реальной практики работы с FastAPI.

Бывает, нужно отправить пользователю ссылку на файл так, чтобы он сразу начал загружаться, без лишних кликов. 🖱💨

Вот как это сделать:

1️⃣ Используйте FileResponse
2️⃣ Установите правильные заголовки
3️⃣ Профит!

Пример кода:
from fastapi.responses import FileResponse

@router.get("/get_my_config/{filename}")
async def get_config_file(filename: str):
full_path = os.path.join(settings.DOWNLOAD_DIR, filename)
if not os.path.exists(full_path):
raise HTTPException(status_code=404, detail="Файл не найден")

return FileResponse(
path=full_path,
filename=filename,
media_type='application/octet-stream',
headers={
"Content-Disposition": f"attachment; filename={filename}",
"Content-Type": "application/octet-stream"
}
)


Главный трюк в заголовках - они говорят браузеру "Эй, это файл для скачивания!" 📥

Надеюсь, этот лайфхак сэкономит вам время и нервы! 😉 Пишите в комментариях, если у вас есть вопросы или свои крутые приемы! 💬
Please open Telegram to view this post
VIEW IN TELEGRAM
👍29🔥87👎1
Друзья, привет!👋

У меня появилась новая идея для статьи на Хабре, и я хотел бы поделиться ею с вами. 🤔

Почему бы не показать на практическом примере, как подключить оплату к Telegram-боту на примере бота для продажи цифровых товаров? 💳

Сейчас, когда цифровые товары становятся все более популярными, создание магазина в Telegram — это отличная возможность для разработчиков и предпринимателей. Я планирую разобрать весь процесс: от создания бота с использованием aiogram 3 до интеграции платежной системы через ЮKassa.

В статье я постараюсь подробно описать:

💎Как настроить бота и организовать каталог товаров.
💎Как реализовать процесс покупки и обработки платежей.
💎Как обеспечить пользователям удобный доступ к купленным материалам.

Если у вас есть идеи или пожелания, что бы вы хотели увидеть в этой статье, пишите в комментариях! Ваше мнение очень важно для меня. 💬
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥95👍226❤‍🔥21💯1🆒1
💡 Проверяем активность пользователей бота на Python (Aiogram 3)

Привет, разработчики! Сегодня делюсь полезным кодом, который может вам пригодиться при работе с телеграм-ботами. 👨‍💻

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

Вот пример решения:

alive_users = 0  
all_count_user_in_db = 100 # Например, общее число пользователей

for user_id in users:
try:
chat = await bot.get_chat(chat_id=user_id)
alive_users += 1
except TelegramBadRequest as e:
# Пользователь заблокировал бота или чат недоступен
print(f"Ошибка при проверке пользователя {user_id}: {e}")
except Exception as e:
# Обработка других непредвиденных ошибок
print(f"Неожиданная ошибка для пользователя {user_id}: {e}")

await message.answer(
f"📊 В базе данных: {all_count_user_in_db} пользователей.\n"
f" Доступны: {alive_users}.\n"
f"🚫 Недоступны: {all_count_user_in_db - alive_users}."
)


🔍 Как это работает:

1️⃣ Считаем активных пользователей через bot.get_chat.
2️⃣ Ловим исключения, чтобы учесть тех, кто заблокировал бота или удалил чат.
3️⃣ Возвращаем статистику пользователю.

Такой подход помогает понимать актуальность вашей базы и анализировать вовлечённость аудитории. 🎯
👍25🔥12👏4
🚀 Привет, друзья! 👋

Если вы читали мою предыдущую статью на Хабре о связке Celery + Redis + FastAPI, то могли заметить, что некоторые практики там выглядят избыточными, а местами не хватает асинхронности — особенно для фоновых задач.

Согласитесь, было бы удобно иметь один проект, где одновременно можно:

запускать FastAPI для основного приложения,
выполнять фоновые задачи,
использовать планировщик задач.

И вот я рад представить вам моё авторское решение проблемы асинхронности и фоновых задач в формате "ВСЁ В ОДНОМ"! 🎉

💡 В реализации я использовал две потрясающие библиотеки:

🔹 APScheduler — проверенное временем решение для отложенных и периодических задач, включая асинхронные.
🔹 FastStream — современный "убийца Celery" для высокопроизводительных фоновых задач.

Не буду утомлять теорией — лучше покажу код. 💻

Весь исходник можно найти по ссылке: 👉 ССЫЛКА

Буду рад вашим комментариям, вопросам и предложениям по улучшению! Пишите! 📝

🔥 Обещаю в будущем подробнее рассказать о своём подходе и почему считаю эту связку "бронебойной"🚀
🔥42👏53👍3❤‍🔥1👎1
📢 Друзья, приветствую!

Сегодня, если успею, подготовлю для вас новое глобальное обновление болванки для разработки телеграмм ботов на Aiogram 3 в связке с SQLAlchemy и базовым классом для работы с базой данных 🚀

🆕 Из нового:

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

⚡️ Для особо нетерпеливых. Мидлвари выглядит так:
from typing import Callable, Dict, Any, Awaitable
from aiogram import BaseMiddleware
from aiogram.types import Message, CallbackQuery
from bot.dao.database import async_session_maker

class DatabaseMiddleware(BaseMiddleware):
async def __call__(
self,
handler: Callable[[Message, Dict[str, Any]], Awaitable[Any]],
event: Message | CallbackQuery,
data: Dict[str, Any]
) -> Any:
async with async_session_maker() as session:
data['session'] = session
try:
return await handler(event, data)
except Exception as e:
await session.rollback()
raise e
finally:
await session.close()


📝 После его необходимо зарегистрировать следующей строкой в main-файле:
dp.update.middleware.register(DatabaseMiddleware())


Затем у вас появится возможность вызывать сессию используя такой синтаксис:
@user_router.message(CommandStart())
async def cmd_start(message: Message, session: AsyncSession):
user_id = message.from_user.id
user_info = await UserDAO.find_one_or_none(
session=session,
filters=TelegramIDModel(telegram_id=user_id)
)


💡 Таким образом код становится более понятным, читаемым и писать кода нужно меньше. Будете ждать?
Please open Telegram to view this post
VIEW IN TELEGRAM
👍42🔥137
Немного прокачал подход по мидлвари в контексте взаимодействия с базой данных. Может кому будет полезно:
from typing import Callable, Dict, Any, Awaitable
from aiogram import BaseMiddleware
from aiogram.types import Message, CallbackQuery

from bot.dao.database import async_session_maker


class BaseDatabaseMiddleware(BaseMiddleware):
async def __call__(
self,
handler: Callable[[Message | CallbackQuery, Dict[str, Any]], Awaitable[Any]],
event: Message | CallbackQuery,
data: Dict[str, Any]
) -> Any:
async with async_session_maker() as session:
self.set_session(data, session)
try:
result = await handler(event, data)
await self.after_handler(session)
return result
except Exception as e:
await session.rollback()
raise e
finally:
await session.close()

def set_session(self, data: Dict[str, Any], session) -> None:
"""Метод для установки сессии в словарь данных."""
raise NotImplementedError("Этот метод должен быть реализован в подклассах.")

async def after_handler(self, session) -> None:
"""Метод для выполнения действий после вызова хендлера (например, коммит)."""
pass


class DatabaseMiddlewareWithoutCommit(BaseDatabaseMiddleware):
def set_session(self, data: Dict[str, Any], session) -> None:
data['session_without_commit'] = session


class DatabaseMiddlewareWithCommit(BaseDatabaseMiddleware):
def set_session(self, data: Dict[str, Any], session) -> None:
data['session_with_commit'] = session

async def after_handler(self, session) -> None:
await session.commit()

Если коротко, то тут генерируется 2 мидлвари: первый делает автоматические коммиты, а второй не делает.

Теперь мы регистрируем их в main-файле:
dp.update.middleware.register(DatabaseMiddlewareWithoutCommit())
dp.update.middleware.register(DatabaseMiddlewareWithCommit())

И теперь вызываем в зависимости от необходимости.

Пример без коммита:
@user_router.callback_query(F.data == "catalog")
async def page_catalog(call: CallbackQuery, session_without_commit: AsyncSession):
await call.answer("Загрузка каталога...")
catalog_data = await CategoryDao.find_all(session=session_without_commit)

await call.message.edit_text(
text="Выберите категорию товаров:",
reply_markup=catalog_kb(catalog_data)
)

Пример с коммитом:
@user_router.message(CommandStart())
async def cmd_start(message: Message, session_with_commit: AsyncSession):
user_id = message.from_user.id
user_info = await UserDAO.find_one_or_none(
session=session_with_commit,
filters=TelegramIDModel(telegram_id=user_id)
)

if user_info:
return await message.answer(
f"👋 Привет, {message.from_user.full_name}! Выберите необходимое действие",
reply_markup=main_user_kb(user_id)
)

values = UserModel(
telegram_id=user_id,
username=message.from_user.username,
first_name=message.from_user.first_name,
last_name=message.from_user.last_name,
)
await UserDAO.add(session=session_with_commit, values=values)
await message.answer(f"🎉 <b>Благодарим за регистрацию!</b>. Теперь выберите необходимое действие.",
reply_markup=main_user_kb(user_id))
14🔥8❤‍🔥3👍3
Media is too big
VIEW IN TELEGRAM
💥 Друзья, добрый вечер! 💥

🎉 Новый проект под предстоящую статью готов! 🎉

Как и обещал, на практическом примере, я демонстрирую вам процесс разработки телеграмм-бота для продажи цифровых товаров. 📲

🛠 Чтобы не усложнять, я намеренно не использовал веб-хуки, мини-апп и прочие технологии, сосредоточившись на самом главном: добавление товаров в магазин и продажи. 📦💵

💳 В качестве платежной системы использована ЮМани. В данном проекте я пошел самым простым путем, интегрировав платежную систему напрямую с ботфазера. 📲🔗 Но, под запрос, я продемонстрирую другой формат интеграции платежки в бота, в том числе и "звезды".

📖 Подробное описание проекта будет в следующей статье на Хабре. 💻

🎥 В видео, прикрепленном к этому посту, вы можете увидеть, как работает бот: «мои покупки», каталог товаров, проведение платежей, добавление товаров и прочий функционал. 📽

🔗 Ссылка на исходник проекта: GitHub

🤖 Ссылка на работающего бота: @DigitalMarketAiogramBot
🔥359👍6👏6
В этот раз, похоже, я превзошел себя по длине статьи 🤦‍♂️. Готовьтесь, будет много кода и немного теории.

Если успею все вычитать, то публикация будет завтра в первой половине дня.

Будете ждать?
🔥103👍26❤‍🔥9👌4
Друзья, доброе утро👋

Только что на Хабре вышла моя новая статья про создание Telegram-бота, который представляет собой полноценный магазин цифровых товаров с админ-панелью, профилем пользователя, каталогом и, конечно, интегрированными платежами прямо в бота! 🛍

В данной статье я продемонстрировал интеграцию платежей через Payments (ЮКасса), напрямую с @BotFather, но в планах будет выпустить продолжение, в рамках которого я хочу перевести этого бота на технологию-веб хуков и дополнительно интегрировать в бота 2 формата оплаты: Telegram-Stars (звезды) и выполнить прямую интеграцию платежки в обход @BotFather через Robokassa.

В рамках данного проекта я использовал следующие технологии:

✔️ Aiogram 3 - лучший фреймворк для разработки телеграмм ботов на Python
✔️ SQLAlchemy 2 - лучший ORM Python для работы с базой данных
✔️ Базу данных SQLITE с асинхронным движком aiosqlite. Благодаря работе с SQLAlchemy 2 вы сможете в пару минут интегрировать вместо SQLITE базы данных любую другую табличчную базу данных.

Ссылки:

📝 Статья: Telegram-бот-магазин на Python: пошаговый гайд с оплатой, каталогом и админкой (Aiogram 3 + SQLAlchemy 2)

🧑‍💻 Исходный код: GitHub (не забудьте оставить звезды, если проект окажется полезным)

🤖 Работающий бот: @DigitalMarketAiogramBot

Материала получилось ОЧЕНЬ много, так что надеюсь на вашу поддержку.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥62👍13❤‍🔥74👌1
💡 Интересный кейс из практики: автоматизация покупок в интернет-магазине 🛍

Друзья, решил поделиться увлекательным кейсом, который недавно реализовал!

📋 Задача:

Есть интернет-магазин, где периодически выставляют товары со скидкой 30-40%. Однако, таких товаров всего 1 экземпляр. Чтобы успеть купить:

1️⃣ Нажимаем «Добавить в корзину»
2️⃣ Переходим в корзину
3️⃣ Жмем «Оформить заказ»

Но есть нюансы:

- Корзина обновляется только после перезагрузки страницы.
- Сессии привязаны к браузеру: в другом браузере корзина не синхронизируется.

🛠 Цель клиента: автоматизировать процесс покупки, чтобы оформить заказ сразу после добавления товара в корзину. При этом клиенту нужно сохранить возможность обновлять страницы и делать покупки из разных мест.

💻 Задачу решил через Python двумя способами:

📌 Способ 1: "Поллинг" на чистом Playwright

🔗 Как это работает:

1️⃣ Запускается браузер и выполняется автоматический вход.
2️⃣ Извлекаются куки, после чего клиент берет управление браузером.
3️⃣ Параллельно запускается второй браузер, где:

- Устанавливаются куки.
- Постоянно обновляется страница корзины.
- При обнаружении товара запускается скрипт, который мгновенно оформляет заказ.

📈 Результат: оформление заказа занимает менее секунды! Это возможно благодаря синхронизации корзин через куки (авторизация завязана на токене в куки).

📌 Способ 2: Веб-хуки + FastStream + Redis

🔗 Как это работает:

Скрипт 1:

1️⃣ Запускает браузер, выполняет вход, извлекает куки и сохраняет их в Redis.
2️⃣ Клиент управляет браузером: кликает, обновляет страницы, добавляет товары в корзину.
3️⃣ При добавлении товара срабатывает триггер через FastStream, который передает задачу второму скрипту.

Скрипт 2:

1️⃣ Запускает второй браузер и извлекает куки из Redis.
2️⃣ Открывает корзину и при получении задачи автоматически оформляет заказ.

📈 Результат: быстрая и надежная синхронизация с использованием современных технологий.

Как вам такой подход?
🔥20👍931🤯1