uk
Feedback

Не попадись на ботовода! Telemetrio знаходить і позначає такі канали мітками 👉 Хочеш бачити мітку, оформляй підписку

Программистика

Программистика

Закритий канал

Лучший канал про python Ссылка для друга: https://t.me/+Ai6ughKtf5g2ZmFi Купить рекламу: https://telega.in/c/+Ai6ughKtf5g2ZmFi Админ: @JeyRahol По рекламе: @ReivuManager

Показати більше
5 790
Підписники
-524 години
+137 днів
-4430 днів
Архів дописів
В Яндексе платят 300.000р, Сбер нуждается в инженерах, а в Тинькофф нехватка кадров «Бигтех по-русски» — место, где разработч
В Яндексе платят 300.000р, Сбер нуждается в инженерах, а в Тинькофф нехватка кадров «Бигтех по-русски» — место, где разработчики из крупных компаний рассказывают правду о работе мечты, зарплатах и жизни в IT. Присоединяйся: @bigtech

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 👍 Состояния — для сложных сценариев
Программистика || #Статья

🚀 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}")
Продолжение поста снизу👇 Программистика || #Статья

🖥 Validators — это библиотека Python, предназначенная для простого и эффективного валидирования данных! В отличие от других
🖥 Validators — это библиотека Python, предназначенная для простого и эффективного валидирования данных! В отличие от других инструментов, требующих определения схем или форм, Validators позволяет проверять отдельные значения без необходимости в сложной настройке. Она предоставляет функции для проверки различных типов данных, включая электронные почты, URL, IP-адреса, доменные имена и другие. 🐱 Ссылка на GitHub Программистика || #Library

🖥 Pydoll — это библиотека для автоматизации браузеров на базе Chromium без WebDriver, предлагающая реалистичную эмуляцию пов
🖥 Pydoll — это библиотека для автоматизации браузеров на базе Chromium без WebDriver, предлагающая реалистичную эмуляцию поведения. Библиотека поддерживает асинхронные функции Python, повышая производительность и позволяя обрабатывать разлинчые события и одновременно выполнять веб-скрапинг.
🐱 Ссылка на GitHub Программистика || #Library

Почему polling не подходит для продакшена?
Anonymous voting

🤖 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 — для прода
Программистика || #Статья

👩‍💻 Добрый, добрый Python с Сергеем Балакиревым Этот курс позволит вам изучить основы программирования на языке Python, нач
👩‍💻 Добрый, добрый Python с Сергеем Балакиревым
Этот курс позволит вам изучить основы программирования на языке Python, начиная с самых азов и заканчивая довольно серьезными конструкциями. После каждого теоретического видеоурока вы найдете практические задания на закрепление пройденного материала. Курс рассчитан и на самых начинающих и для тех, кто уже знаком с Python, но хотел бы повысить, а заодно и проверить, свой уровень.
🌐 Ссылка
Программистика || #Course

👩‍💻 Wowy — это шаблон интернет-магазина, построенный на Django 4.x, который предоставляет полный набор функций для управлен
👩‍💻 Wowy — это шаблон интернет-магазина, построенный на Django 4.x, который предоставляет полный набор функций для управления! Она обеспечивает удобный пользовательский интерфейс и мощную панель администратора. Включает поддержку управления товарами (с множеством изображений), управление категориями, корзину, список желаний, генерацию PDF-счетов и детальную аналитику продаж.
🐱 Ссылка на GitHub Программистика || #Library

СОБЫТИЕ.Новогодние скидки до 8% в парк-квартале В СОБЫТИИ на Мосфильмовской – ограниченный пул квартир с праздничной выгодой! Не упустите уникальную возможность переехать в готовый квартал с современной инфраструктурой и парком. • Камерный формат: секции от 10 этажей, от 3 квартир на этаже • Потолки до 6,24 м, окна редкой высоты – 2,76 м • Эксклюзивные лоты: двусветные, с террасами, каминами, окнами в пол, окнами в ванных • Элегантное лобби: авторский интерьер, эксклюзивная мебель, дизайнерские светильники • В доме – фитнес-рум, детская, репетиторская, коворкинг • Общественные террасы на крышах • Природный парк 12 га рядом с домом Спешите с покупкой, количество квартир ограничено! Перейти на сайт #реклама dom-sobytie.ru О рекламодателе

Что произойдет, если в дочернем классе переопределить метод без вызова super()?
Anonymous voting

⚙️ ООП в 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() — твой амулет от багов 🟢 Композиция и протоколы — ключ к гибкому, масштабируемому коду
Программистика || #Статья

😈 Senior-безопасник создал крутейший канал про ИБ Благодаря простым картинкам даже новичок поймет основы хакинга и информаци
+4
😈 Senior-безопасник создал крутейший канал про ИБ Благодаря простым картинкам даже новичок поймет основы хакинга и информационной безопасности. Присоединяйтесь: @infosec

Программистика|| #Шпаргалка
Программистика|| #Шпаргалка

Профессия: Python-разработчик Книга позволит вам получить знания, достаточные для профессии Python-разработчик (начиная с уро
Профессия: Python-разработчик
Книга позволит вам получить знания, достаточные для профессии Python-разработчик (начиная с уровня Junior Developer). Это даст вам возможность устройства на работу программистом, или возможность работать на себя – искать заказы на фриланс-биржах, создавать свои собственные приложения и игры, а затем выпускать их на таких площадках как Google Play, Steam и подобных.
Программистика|| #Книги

Роадмап Python разработчика — Что учить / На что забить [2025]
📱 Первоисточник
Программистика|| #video