Программистика
Закрытый канал
Лучший канал про python Ссылка для друга: https://t.me/+Ai6ughKtf5g2ZmFi Купить рекламу: https://telega.in/c/+Ai6ughKtf5g2ZmFi Админ: @JeyRahol По рекламе: @ReivuManager
Больше5 790
Подписчики
-524 часа
+137 дней
-4430 дней
Архив постов
5 790
В Яндексе платят 300.000р, Сбер нуждается в инженерах, а в Тинькофф нехватка кадров
«Бигтех по-русски» — место, где разработчики из крупных компаний рассказывают правду о работе мечты, зарплатах и жизни в IT.
Присоединяйся: @bigtech
5 790
4️⃣ Работа с файлами
Приём файла от пользователя:
@bot.message_handler(content_types=['document'])
def handle_document(message):
file_info = bot.get_file(message.document.file_id)
downloaded_file = bot.download_file(file_info.file_path)
# Сохраняем локально
with open(f"files/{message.document.file_name}", 'wb') as new_file:
new_file.write(downloaded_file)
bot.reply_to(message, "✅ Файл получен!")
📎 Для больших файлов используй потоковую обработку, не загружай всё в память!
Приём файла от пользователя:
@bot.message_handler(content_types=['document'])
def handle_document(message):
file_info = bot.get_file(message.document.file_id)
downloaded_file = bot.download_file(file_info.file_path)
# Сохраняем локально
with open(f"files/{message.document.file_name}", 'wb') as new_file:
new_file.write(downloaded_file)
bot.reply_to(message, "✅ Файл получен!")
Отправка файла пользователю:
@bot.message_handler(commands=['getfile'])
def send_file(message):
with open('report.pdf', 'rb') as file:
bot.send_document(message.chat.id, file)
📎 Для больших файлов используй потоковую обработку, не загружай всё в память!
5️⃣ Платежи через Telegram
Telegram поддерживает встроенные платежи (Stripe, ЮKassa и др.).
from telebot.types import LabeledPrice
@bot.message_handler(commands=['buy'])
def send_invoice(message):
prices = [LabeledPrice(label='Подписка на месяц', amount=50000)] # в копейках
bot.send_invoice(
chat_id=message.chat.id,
title='Премиум подписка',
description='Доступ ко всем функциям бота',
invoice_payload='premium_subscription',
provider_token='YOUR_PAYMENT_TOKEN',
currency='RUB',
prices=prices,
start_parameter='subscription'
)
@bot.pre_checkout_query_handler(func=lambda query: True)
def checkout(pre_checkout_query):
bot.answer_pre_checkout_query(pre_checkout_query.id, ok=True)
@bot.message_handler(content_types=['successful_payment'])
def successful_payment(message):
# Активируем подписку в БД
activate_premium(message.from_user.id)
bot.send_message(message.chat.id, "✅ Оплата прошла успешно!")
6️⃣ Состояния пользователя (FSM)
Для многошаговых сценариев (регистрация, опросы):
from telebot.handler_backends import State, StatesGroup
from telebot.storage import StateMemoryStorage
state_storage = StateMemoryStorage()
bot = TeleBot("TOKEN", state_storage=state_storage)
class UserStates(StatesGroup):
name = State()
age = State()
@bot.message_handler(commands=['register'])
def start_registration(message):
bot.send_message(message.chat.id, "Как тебя зовут?")
bot.set_state(message.from_user.id, UserStates.name, message.chat.id)
@bot.message_handler(state=UserStates.name)
def get_name(message):
bot.send_message(message.chat.id, f"Приятно познакомиться, {message.text}! Сколько тебе лет?")
with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
data['name'] = message.text
bot.set_state(message.from_user.id, UserStates.age, message.chat.id)
@bot.message_handler(state=UserStates.age)
def get_age(message):
with bot.retrieve_data(message.from_user.id, message.chat.id) as data:
data['age'] = message.text
bot.send_message(message.chat.id, f"{data['name']}, {data['age']} лет — записал!")
bot.delete_state(message.from_user.id, message.chat.id)
🧪 Бонус: мониторинг и логирование
Интеграция с Sentry для отслеживания ошибок:
import sentry_sdk
sentry_sdk.init(
dsn="YOUR_SENTRY_DSN",
traces_sample_rate=1.0
)
# Теперь все ошибки автоматически отправляются в Sentry
💡 Запомни:
👍 Webhook — обязателен для продакшена 👍 Рассылки — с контролем скорости и асинхронно 👍 Админ-права — проверяй всегда 👍 Файлы — не грузи в память целиком 👍 Платежи — только через официальный API 👍 Состояния — для сложных сценариевПрограммистика || #Статья
5 790
🚀 Telegram-бот: продвинутые фичи без магии
Сделал бота с командами /start и /help? Поздравляю, ты на уровне "Hello, World!". Но настоящие боты делают рассылки, принимают платежи, работают с файлами и имеют админку. Разбираемся, как это сделать без костылей.
🧱 Типичные ошибки продвинутых новичков
🟢 Делают рассылку в один поток — блокируют бота на часы:
for user_id in users:
bot.send_message(user_id, "Рассылка")
На 10k пользователей — это несколько часов. Telegram API ограничивает скорость.
🟢 Хранят файлы в памяти — бот падает на больших файлах:
file = bot.download_file(file_path)
# file весит 50MB — бот умер
🟢 Не проверяют права админов — любой юзер может управлять ботом:
@bot.message_handler(commands=['admin'])
def admin_panel(message):
# без проверки прав!
🟢 Webhook настраивают неправильно — бот не получает сообщения или падает.
📌 Как делать правильно
1️⃣ Webhook вместо polling (продакшен)
Polling — для теста. Webhook — для боевого режима.
from flask import Flask, request
import telebot
app = Flask(__name__)
bot = telebot.TeleBot("YOUR_TOKEN")
WEBHOOK_URL = "https://yourdomain.com/webhook"
@app.route('/webhook', methods=['POST'])
def webhook():
if request.headers.get('content-type') == 'application/json':
json_string = request.get_data().decode('utf-8')
update = telebot.types.Update.de_json(json_string)
bot.process_new_updates([update])
return '', 200
else:
return '', 403
@app.route('/set_webhook')
def set_webhook():
bot.remove_webhook()
bot.set_webhook(url=WEBHOOK_URL)
return "Webhook установлен!", 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8443, ssl_context=('cert.pem', 'key.pem'))
📎 Нужен SSL-сертификат (Let's Encrypt или самоподписанный).
2️⃣ Рассылка с контролем скорости
Telegram ограничивает: максимум 30 сообщений в секунду.
import time
import logging
def broadcast(users, message_text):
success = 0
failed = 0
for user_id in users:
try:
bot.send_message(user_id, message_text)
success += 1
time.sleep(0.05) # ~20 сообщений/сек
except Exception as e:
logging.error(f"Не удалось отправить {user_id}: {e}")
failed += 1
logging.info(f"Рассылка завершена: {success} успешно, {failed} ошибок")
Для больших баз (100k+) используй асинхронную библиотеку aiogram:
import asyncio
from aiogram import Bot
async def broadcast_async(users, text):
bot = Bot(token="YOUR_TOKEN")
tasks = [bot.send_message(user_id, text) for user_id in users]
await asyncio.gather(*tasks, return_exceptions=True)
await bot.session.close()
3️⃣ Админ-панель с проверкой прав
Храни список админов в конфиге или базе:
ADMINS = [123456789, 987654321] # ID админов
def is_admin(user_id):
return user_id in ADMINS
@bot.message_handler(commands=['admin'])
def admin_panel(message):
if not is_admin(message.from_user.id):
bot.send_message(message.chat.id, "❌ Доступ запрещён")
return
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("📊 Статистика", callback_data="stats"))
markup.add(InlineKeyboardButton("📢 Рассылка", callback_data="broadcast"))
bot.send_message(message.chat.id, "Админ-панель:", reply_markup=markup)
@bot.callback_query_handler(func=lambda call: call.data == "stats")
def show_stats(call):
if not is_admin(call.from_user.id):
return
# Получаем статистику из БД
user_count = get_user_count() # твоя функция
bot.send_message(call.message.chat.id, f"👥 Пользователей: {user_count}")
Продолжение поста снизу👇
Программистика || #Статья5 790
🖥 Validators — это библиотека Python, предназначенная для простого и эффективного валидирования данных!
В отличие от других инструментов, требующих определения схем или форм, Validators позволяет проверять отдельные значения без необходимости в сложной настройке. Она предоставляет функции для проверки различных типов данных, включая электронные почты, URL, IP-адреса, доменные имена и другие.
🐱 Ссылка на GitHub
Программистика || #Library
5 790
🖥 Pydoll — это библиотека для автоматизации браузеров на базе Chromium без WebDriver, предлагающая реалистичную эмуляцию поведения. Библиотека поддерживает асинхронные функции Python, повышая производительность и позволяя обрабатывать разлинчые события и одновременно выполнять веб-скрапинг.🐱 Ссылка на GitHub Программистика || #Library
5 790
🤖 Telegram-бот без иллюзий: от первой строки до продакшена
Все хотят бота: "сделай мне крипто-трекер", "автопостинг в канал", "магазин с оплатой". Но между "Hello, World!" и рабочим ботом — пропасть из костылей, которые ты не видишь в туториалах.
🧱 Типичные ошибки новичков
🟢 Запускают бота через polling на сервере:
bot.polling()
В продакшене это убивает сервер — бот постоянно дёргает API, жрёт ресурсы и падает при любом сбое сети.
🟢 Хранят токен прямо в коде:
TOKEN = "123456:ABC-DEF..."
bot = Bot(token=TOKEN)
Запушил в Git — токен утёк. Всё, начинай заново.
🟢 Не обрабатывают ошибки:
@bot.message_handler(commands=['start'])
def start(message):
bot.send_message(message.chat.id, "Привет")
➡️Юзер отправил команду, а бот упал из-за сетевой ошибки — и молчит.
🟢 Пишут всю логику в одном файле на 1000+ строк — потом не могут найти баг.
📌 Как делать правильно
1️⃣ Установка библиотеки
Две главные библиотеки:
🟢 python-telegram-bot — async, мощная, для сложных ботов
🟢pyTelegramBotAPI (telebot) — проще для старта
pip install pyTelegramBotAPI
2️⃣ Храни токен в .env
Создай файл .env:
BOT_TOKEN=123456:ABC-DEF...В коде:
import os
from dotenv import load_dotenv
from telebot import TeleBot
load_dotenv()
TOKEN = os.getenv('BOT_TOKEN')
bot = TeleBot(TOKEN)
📎 Не забудь добавить .env в .gitignore!
3️⃣ Базовая структура бота
import os
from dotenv import load_dotenv
from telebot import TeleBot
import logging
# Настройка логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
load_dotenv()
bot = TeleBot(os.getenv('BOT_TOKEN'))
@bot.message_handler(commands=['start'])
def start(message):
bot.send_message(
message.chat.id,
f"Привет, {message.from_user.first_name}!"
)
@bot.message_handler(commands=['help'])
def help_command(message):
bot.send_message(
message.chat.id,
"Доступные команды:\n/start - Начать\n/help - Помощь"
)
@bot.message_handler(func=lambda message: True)
def echo(message):
bot.reply_to(message, f"Ты написал: {message.text}")
if __name__ == '__main__':
logging.info("Бот запущен")
bot.polling(none_stop=True)
4️⃣ Кнопки и клавиатуры
Inline-кнопки (под сообщением):
from telebot.types import InlineKeyboardMarkup, InlineKeyboardButton
@bot.message_handler(commands=['menu'])
def menu(message):
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("Опция 1", callback_data="opt1"))
markup.add(InlineKeyboardButton("Опция 2", callback_data="opt2"))
bot.send_message(message.chat.id, "Выбери:", reply_markup=markup)
@bot.callback_query_handler(func=lambda call: True)
def callback_handler(call):
if call.data == "opt1":
bot.answer_callback_query(call.id, "Ты выбрал опцию 1")
Обычная клавиатура:
from telebot.types import ReplyKeyboardMarkup, KeyboardButton
@bot.message_handler(commands=['keyboard'])
def keyboard(message):
markup = ReplyKeyboardMarkup(resize_keyboard=True)
markup.add(KeyboardButton("Кнопка 1"))
markup.add(KeyboardButton("Кнопка 2"))
bot.send_message(message.chat.id, "Используй кнопки:", reply_markup=markup)
5️⃣ Обработка ошибок
import time
def safe_polling():
while True:
try:
bot.polling(none_stop=True, timeout=60)
except Exception as e:
logging.error(f"Ошибка: {e}")
time.sleep(5) # Пауза перед перезапуском
if __name__ == '__main__':
safe_polling()
6️⃣ Структура проекта для больших ботов
bot_project/
├── .env # Токены и секреты
├── .gitignore
├── main.py # Запуск бота
├── config.py # Настройки
├── handlers/ # Обработчики команд
│ ├── start.py
│ ├── menu.py
│ └── admin.py
├── database/ # Работа с БД
│ └── db.py
└── utils/ # Вспомогательные функции
└── helpers.py
💡 Запомни:
🟢 Токен — в .env, никогда в код 🟢 Логируй всё важное — иначе не поймёшь, где упал 🟢 Polling — для теста, webhook — для продаПрограммистика || #Статья
5 790
👩💻 Добрый, добрый Python с Сергеем Балакиревым
Этот курс позволит вам изучить основы программирования на языке Python, начиная с самых азов и заканчивая довольно серьезными конструкциями. После каждого теоретического видеоурока вы найдете практические задания на закрепление пройденного материала. Курс рассчитан и на самых начинающих и для тех, кто уже знаком с Python, но хотел бы повысить, а заодно и проверить, свой уровень.
🌐 СсылкаПрограммистика || #Course
5 790
👩💻 Wowy — это шаблон интернет-магазина, построенный на Django 4.x, который предоставляет полный набор функций для управления! Она обеспечивает удобный пользовательский интерфейс и мощную панель администратора. Включает поддержку управления товарами (с множеством изображений), управление категориями, корзину, список желаний, генерацию PDF-счетов и детальную аналитику продаж.🐱 Ссылка на GitHub Программистика || #Library
5 790
СОБЫТИЕ.Новогодние скидки до 8% в парк-квартале
В СОБЫТИИ на Мосфильмовской – ограниченный пул квартир с праздничной выгодой! Не упустите уникальную возможность переехать в готовый квартал с современной инфраструктурой и парком.
• Камерный формат: секции от 10 этажей, от 3 квартир на этаже
• Потолки до 6,24 м, окна редкой высоты – 2,76 м
• Эксклюзивные лоты: двусветные, с террасами, каминами, окнами в пол, окнами в ванных
• Элегантное лобби: авторский интерьер, эксклюзивная мебель, дизайнерские светильники
• В доме – фитнес-рум, детская, репетиторская, коворкинг
• Общественные террасы на крышах
• Природный парк 12 га рядом с домом
Спешите с покупкой, количество квартир ограничено!
Перейти на сайт
#реклама
dom-sobytie.ru
О рекламодателе
5 790
Что произойдет, если в дочернем классе переопределить метод без вызова super()?
5 790
⚙️ ООП в Python без иллюзий: класс — это не серебряная пуля
Многие упарываются по классам и наследованию, но жесткая реальность: в продакшене эти приёмы часто усложняют поддерживаемость и вызывают неожиданные баги.
🧱 Классические заблуждения старичков
🟢 "Всё наследуем!"
class A: ... class B(A): ...На деле — усложнение и хрупкая иерархия. Часто проще композиция через объекты. 🟢 Overriding ради overriding — забыли
super()
class Base:
def run(self): ...
class Child(Base):
def run(self): ... # забыли super().run()
— появление скрытых багов в поведении.
🟢 Миксуют классы и dataclasses, получая конфликт методов и неявное дублирование данных.
🟢 Используют магические методы getattr/setattr для "красоты", не просчитав риски перехвата важных атрибутов → глухие баги.
📌 Как делать правильно
1️⃣ Наследование — в крайних случаях. Если можно — композиция через свойства и методы. 2️⃣ Всегда вызывай super(), если перекрываешь родительские методы (особенно init и del). Это защищает от потери важной логики базового класса. 3️⃣ Не смешивай dataclass и обычные классы без крайней необходимости. В dataclass — только структура, в обычных классах — поведение. 4️⃣ Если нужно динамическое управление атрибутами — используй slots или property, а не магию getattr.🧪 Бонус: абстракция через protocol from typing import Protocol
class Runner(Protocol):
def run(self) -> None: ...
def process(r: Runner):
r.run()
💡 Запомни
🟢 Класс — не магия, а удобный контейнер для кода 🟢 Наследование опасно без хорошей причинно-следственной связи 🟢 super() — твой амулет от багов 🟢 Композиция и протоколы — ключ к гибкому, масштабируемому кодуПрограммистика || #Статья
5 790
😈 Senior-безопасник создал крутейший канал про ИБ
Благодаря простым картинкам даже новичок поймет основы хакинга и информационной безопасности.
Присоединяйтесь: @infosec
5 790
Профессия: Python-разработчик
Книга позволит вам получить знания, достаточные для профессии Python-разработчик (начиная с уровня Junior Developer). Это даст вам возможность устройства на работу программистом, или возможность работать на себя – искать заказы на фриланс-биржах, создавать свои собственные приложения и игры, а затем выпускать их на таких площадках как Google Play, Steam и подобных.Программистика|| #Книги
5 790
Роадмап Python разработчика — Что учить / На что забить [2025]
📱 ПервоисточникПрограммистика|| #video
