Python Web & Scripts — Django, FastAPI, скрипты
436 subscribers
19 photos
2 videos
24 links
Python для веба и автоматизации: Django, FastAPI, Flask, Starlette. Скрипты для парсинга, ETL, обработки данных, integrations. Async, pydantic, deployment patterns.
Канал сети public.tg.
Download Telegram
Flask ломают не роуты, а отсутствие границ между кодом и инфраструктурой

В Flask слишком легко начать с «одного файла» и незаметно притащить в него всё: конфиг, бизнес-логику, SQL, шаблоны, интеграции. Через месяц такой app.py уже не поддерживается, а любой новый эндпоинт требует раскопок по всему проекту.

Рабочая схема простая:
— app factory вместо глобального app;
— blueprints для разрезания домена по модулям;
— отдельные слои для сервисов, репозиториев и адаптеров;
— конфиг через окружение, а не через хардкод;
— расширения и middleware подключать в одном месте, а не по всему коду.

Ещё одна типовая ошибка — тащить в view всё подряд. View должен принимать запрос, валидировать вход, вызвать сервис и вернуть ответ. Если в нём есть SQL-запросы, HTTP-клиенты и ветвления на 80 строк, проект уже не Flask-лайт, а монолит без структуры.

Для фоновых задач и внешних интеграций лучше сразу отделять их от request-response цикла: очереди, отдельные воркеры, явные таймауты и ретраи. Иначе любой медленный API начнёт тормозить весь веб-поток.

Если Flask нужен в проде, держите его как тонкий HTTP-слой, а не как место, где живёт вся логика. Тогда приложение остаётся маленьким по коду, но большим по масштабу.
Scrapy ломается не на парсинге, а на грязном каркасе проекта

За неделю в репах: у рабочих краулеров чаще всего текут не селекторы, а архитектура. Если Spider знает про БД, ретраи и формат выгрузки, его почти невозможно переиспользовать без боли.

Держите три слоя отдельно:
— Spider: только запросы и извлечение полей
— Pipeline: валидация, нормализация, запись
— Item: единая схема данных, а не «dict как получится»

Самые частые ошибки в Scrapy:
— дубли из-за слабого dupefilter и кривых start_urls
— падения на пустых полях, когда нет default и проверки типов
— тяжёлые parse-методы, где внутри и логика, и сеть, и форматирование

Если проект растёт, сразу добавляйте:
— явные таймауты и лимиты на глубину
— отдельный слой для экспорта в CSV/JSON/БД
— логирование причин пропуска, а не только ошибок

Scrapy хорош там, где поток данных должен быть предсказуемым. Чем раньше вы отделите сбор от обработки, тем меньше времени уйдёт на «починку парсера» вместо работы с данными.
Starlette ломают не роуты, а мелкие ошибки в ASGI-границах

Starlette часто берут как «лёгкий каркас», а потом удивляются странным багам под нагрузкой. За неделю в репах обычно всплывают одни и те же места: request body читают дважды, фоновые задачи начинают жить своей жизнью, middleware меняет поведение ответа уже после отправки.

Проверьте базовый набор:
— не читайте stream/body в разных слоях без явного кеша;
— не держите тяжёлую логику в middleware, если она может быть зависимостью или endpoint-ом;
— не смешивайте sync-код с async без понятного границами вызова;
— для долгих операций выносите работу в очередь, а не в response cycle.

Ещё одна частая проблема — обработка исключений. Если вы ловите всё подряд и возвращаете «красивый» 200, отладка превращается в археологию. Лучше явно разделять: валидация, ожидаемые доменные ошибки, и настоящий 500 с логом и trace-id.

Если Starlette кажется капризным, обычно каприз не в нём, а в том, что в приложении не определены границы ответственности. Держите transport, бизнес-логику и фоновые задачи раздельно — и каркас перестаёт удивлять.
This media is not supported in your browser
VIEW IN TELEGRAM
Армения заблокирует онлайн-казино для получающих пособия

Армения ввела жёсткие ограничения на онлайн-гемблинг: запретила депозиты для получателей соцпособий и пенсий, ограничила остальным суммы до 20% дохода, обязала казино добавить кнопку самозапрета. Сайты, не подчинившиеся требованиям, будут заблокированы — технология реализации неясна. Проблемы с платёжками неизбежны. Криптоказино, вероятно, останутся без контроля, что открывает новый канал для залива трафика.

➡️ Читайте на сайте: https://aff.top/blog/armeniia-zablokiruet-onlain-kazino-dlia-poluchaiuschikh-posobiia

🧠 Ещё больше инсайтов → в канале AFF.top
This media is not supported in your browser
VIEW IN TELEGRAM
В DeepSeek добавили распознавание изображений

DeepSeek запустил бета-версию распознавания изображений — функция доступна бесплатно прямо в чате. Работает нестабильно, но для базовых задач подходит: например, проверить, есть ли на креативе узнаваемая знаменитость в нужном гео. Платная подписка не нужна.

➡️ Читайте на сайте: https://aff.top/blog/v-deepseek-dobavili-raspoznavanie-izobrazhenii

🧠 Ещё больше инсайтов → в канале AFF.top
This media is not supported in your browser
VIEW IN TELEGRAM
📡 Запустили AFF.TOP — медиа про арбитраж, ИИ и вайб-кодинг

Разбираем новости из мира ИИ, тренды вайб-кодинга, инсайды индустрии арбитража — без воды и продаж курсов.

👉 Подписаться на канал AFF.TOP
asyncio ломают не await, а неправильные границы задач и блокирующий код

За неделю в репах чаще всего вижу один и тот же паттерн: async-функции есть, а поведение — как у обычного скрипта с подвисаниями. Причина обычно в двух местах:
— внутри корутины спрятан sync I/O: requests, тяжелый парсинг, запись на диск
— задачи запускают, но не собирают ошибки и не ограничивают параллелизм

Если внутри event loop появляется блокировка, он перестает обслуживать остальные корутины. Поэтому любой код, который может ждать сеть, БД или файловую систему, надо либо уносить в нативный async-стек, либо выносить в thread/process pool. Иначе asyncio превращается в красивую обертку над последовательным выполнением.

Второй частый провал — “создали 1000 задач и ждем”. Так код легко убить памятью и внешним API. Нормальная схема: очередь, семафор, timeout, явная обработка исключений. И еще правило: если задача не нужна в фоне, не делайте fire-and-forget без ссылки и логирования.

Проверьте свой проект одной правкой: найдите все места, где async-функция вызывает sync-библиотеку без адаптера. Обычно после этого становятся видны и тормоза, и странные таймауты, и “пропавшие” ошибки.
7 привычек в Python, которые экономят часы на отладке и рефакторинге

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

— Проверяйте входные данные у края системы: из request, очереди, файла, CLI. Внутри кода уже работайте с чистыми объектами.
— Не смешивайте бизнес-логику и I/O: чтение, сеть, БД, логирование лучше выносить в отдельные слои.
— Используйте исключения только для исключений, а не как ветвление.
— Для async-кода держите под контролем точки await: там чаще всего прячутся гонки и неожиданные зависания.

Ещё одна полезная привычка — писать код так, чтобы его можно было запустить в тесте без внешней среды. Если функция зависит только от аргументов, её проще покрыть юнит-тестом, переиспользовать в воркере и безопасно переписать.

Если хочется меньше боли в поддержке, начинайте не с «красивого» кода, а с предсказуемого: явные контракты, чистые границы и минимум магии.
This media is not supported in your browser
VIEW IN TELEGRAM
Google заставляет махать руками перед камерой

Google запустила новую капчу на основе распознавания движений — требует включённую камеру и помах руки перед экраном для подтверждения. Система отслеживает 21 точку-координату положения руки в реальном времени, а данные удаляются сразу после проверки. Для арбитражников это усложнит автоматизацию — обход вероятно будет работать через перехват хэша с положительным ответом. Капча пока на тестировании, но предвещает новый уровень защиты от ботов в и…

➡️ Читайте на сайте: https://aff.top/blog/google-zastavliaet-makhat-rukami-pered-kameroi

🧠 Ещё больше инсайтов → в канале AFF.top
Автоматизация ломается не в коде, а в предположениях о входных данных

Скрипт для парсинга, отчётов или синхронизации обычно пишут под «нормальный» кейс: один формат, одна схема, один источник. Потом в бою прилетает пустое поле, лишний символ, дубль или таймаут — и пайплайн молча портит данные.

Что помогает держать автоматизацию живой:
— валидировать вход на границе: pydantic, явные проверки, whitelist полей;
— делать операции идемпотентными: повторный запуск не должен плодить дубли;
— отделять сбор данных от записи: сначала сырой слой, потом преобразование;
— логировать не только ошибки, но и «подозрительные успехи»: пустые ответы, частичные выборки, неожиданные типы.

Ещё одна типовая ошибка — смешивать бизнес-логику и инфраструктуру. Когда парсер сам решает, как ретраить, как маппить поля и куда слать уведомление, его трудно тестировать и ещё труднее менять. Лучше держать шаги отдельно: fetch → validate → transform → store → notify.

Если автоматизация должна жить долго, проектируйте её как набор маленьких повторяемых операций, а не как один «магический» скрипт: так она переживёт любой шум во входных данных.
This media is not supported in your browser
VIEW IN TELEGRAM
Как заработать 2500$ с УБТ трафика из Twitter’а не привлекая внимания санитаров

Арбитражник проkил органическbq трафик с X (Twitter) через связку с dating-офферами, используя маскировку ссылок под видеопревью. После полугода залива с марта по октябрь 2025-го он заработал скромный, но стабильный доход, внедрив динамическую генерацию страниц, обфускацию ссылок и cookie-разделение трафика для увеличения конверсии на треть. Основной вызов — постоянные баны доменом из-за обновлений Google и требований антифрода, из…

➡️ Читайте на сайте: https://aff.top/blog/kak-zarabotat-2500-s-ubt-trafika-iz-twitter-a-ne-privlekaia-vnimaniia-sanitarov

🧠 Ещё больше инсайтов → в канале AFF.top
asyncio ломается не там, где await забыли, а там, где смешали блокировки и гонки

В Python async помогает держать много I/O-задач без лишних потоков, но не делает код «быстрым сам по себе». Если внутри корутины есть sync-вызов, долгий CPU-цикл или скрытая блокировка, event loop замирает, а остальные задачи ждут.

Проверьте три места:
• сетевые клиенты и драйверы — должны быть реально async, а не обёрткой над sync;
• тяжёлые вычисления — выносите в process pool или отдельный worker;
• общие объекты — защищайте lock’ами, иначе ловите race condition даже без потоков.

Ещё один частый провал — бесконтрольный create_task. Если задачу не сохранить, не дождаться и не обработать исключение, ошибки исчезают в тишину. Для фоновых работ нужен явный список задач, отмена по shutdown и сбор результатов через gather или as_completed.

Если коротко: в asyncio важно не «писать await везде», а убирать блокировки, ограничивать конкурентность и заранее продумывать отмену. Тогда async даёт предсказуемую нагрузку, а не красивую иллюзию параллельности.
5 мест в FastAPI, где чаще всего прячутся баги интеграций и падение производительности

FastAPI любят за скорость старта, но в проде боль обычно не в роутинге, а в мелочах вокруг него. Есть наблюдение которое стоит проверить: если API «тормозит», причина часто в валидации, блокирующем коде и лишних преобразованиях данных.

• Не тяните тяжёлые запросы в синхронные функции внутри async-эндпоинта. Один `requests.get()` или работа с файлом без выноса в пул — и event loop уже занят.
• Не делайте сложные Pydantic-схемы на каждый чих. Глубокие вложенности, кастомные валидаторы и лишние `model_dump()` съедают время на горячих путях.
• Не смешивайте транспорт и доменную логику в одном обработчике. Чем тоньше endpoint, тем проще тестировать, профилировать и переиспользовать код.

Ещё один частый провал — ответы с лишними полями и неявной сериализацией. Если отдаёте ORM-объекты как есть, проверьте, что нет скрытых обращений к базе и ленивых связей. В интеграциях это особенно заметно: один эндпоинт выглядит невинно, а под нагрузкой внезапно начинает делать десятки лишних операций.

Для стабильного API держите правило: в endpoint — минимум логики, внутри — явные async/sync границы, снаружи — схемы и контракты, которые не заставляют Python работать больше, чем нужно.
5 ошибок в Python-скриптах, из-за которых автоматизация ломается на ровном месте

Скрипт может «работать у тебя», но падать на сервере, в cron или в пайплайне. Чаще всего проблема не в Python, а в том, как написан вход, выход и обработка ошибок.

— Не проверяют входные данные: пустые строки, битый JSON, неожиданные ключи. Любой парсер должен падать предсказуемо, а не в середине цепочки.
— Ловят Exception везде подряд. В итоге ошибка скрыта, а задача помечена как успешная.
— Пишут всё в один файл без ротации и без явного пути. Потом лог теряется, права не совпадают, а отладка превращается в квест.

Ещё две типовые проблемы: зависимость от текущей директории и отсутствие таймаутов в HTTP-запросах. Первый пункт ломает запуск из cron и CI, второй — вешает воркер на неопределённое время.

Если скрипт нужен не «для себя», а как часть процесса, добавь три вещи: явные пути, нормальные исключения с кодом выхода и таймауты на внешние запросы. Тогда автоматизация перестанет быть хрупкой.
asyncio ломается не в коде, а в месте, где вы смешали ожидание и блокировку

Главная ошибка — считать, что async сам ускоряет всё подряд. Он хорошо работает там, где есть ожидание сети, диска, очереди или таймера. Как только внутри корутины появляется тяжёлый CPU-кусок, синхронный ORM-вызов или sleep из стандартной библиотеки, event loop начинает простаивать.

Есть три типовых правила:
— не вызывайте блокирующие функции из корутины без выноса в thread/process pool;
— не плодите задачи без лимита, иначе получите не скорость, а очередь и память;
— не путайте await с параллельностью: порядок выполнения решает планировщик, а не ваш список вызовов.

Если нужен контроль, стройте узкие места явно: ограничитель concurrency через Semaphore, таймауты на внешние запросы, отдельный пул для тяжёлых операций. Для интеграций это почти всегда важнее, чем «перевести всё на async».

Проверка простая: если убрать внешнее ожидание, а код почти не теряет время — asyncio вам нужен не для ускорения, а для управляемого I/O.
asyncio ломается не там, где «медленно», а там, где его кормят блокировками

За неделю в репах чаще всего всплывают одни и те же ошибки:
— внутри корутины вызывают тяжелый sync-код: requests, ORM без async, файловые операции;
— забывают про лимиты параллелизма и запускают сотни задач через gather без контроля;
— держат один общий client/session и не закрывают его;
— ловят исключения только в одной задаче, а остальные тихо падают.

Если есть I/O, используй await до конца цепочки. Если попался синхронный кусок, выноси его в thread pool или отдельный процесс. Иначе event loop начинает обслуживать не задачи, а ожидание чужих блокировок.

Для контроля нагрузки нужны семафоры, очереди и явные таймауты. Без них asyncio легко превращается в генератор случайных зависаний: внешняя API отвечает медленно, а у тебя уже забиты все воркеры и растет хвост из висящих задач.

Еще одна типовая ошибка — отсутствие отмены и cleanup. Task cancelled не должен оставлять открытые соединения, незакрытые файлы и полумертвые записи в БД. Лучше один раз написать аккуратный finally, чем потом искать утечки по логам.

Главное правило: asyncio ускоряет только то, что умеет ждать. Все остальное он просто делает более заметным.
Pydantic ломают не типы, а привычка валидировать «на глаз»

Если модель используется как контракт, держите в ней только входные данные и правила проверки. Не тащите туда бизнес-логику, запросы к БД и вычисления, которые зависят от окружения — иначе объект становится неудобным и плохо тестируется.

Есть наблюдение которое стоит проверить: большинство багов рождается не в самих полях, а на границе между сырым словарём и моделью. Там полезно явно фиксировать:
— обязательные поля и значения по умолчанию;
— алиасы для внешнего API;
— строгие типы там, где нельзя «догадываться»;
— отдельные модели для входа и ответа.

Ещё одна типовая ошибка — полагаться на «автоматическое приведение». Строка в число, пустая строка в None, лишний ключ в payload — всё это удобно до первого инцидента. Если формат важен, лучше сделать ошибку явной, чем потом искать, почему данные тихо исказились 🔧

Для сложных payload’ов помогает правило: одна модель — одна задача. Вложенные структуры разбивайте на маленькие схемы, а преобразования выносите в отдельные функции. Тогда сериализация, валидация и тесты перестают мешать друг другу.

Итог простой: Pydantic особенно силён там, где нужно жёстко описать границу системы. Чем раньше выловили мусорный вход, тем меньше кода придётся чинить дальше по цепочке.
5 ошибок в FastAPI, которые ломают проект раньше, чем нагрузка

FastAPI легко стартует, и из-за этого в нем часто пропускают базовую архитектуру. Потом появляются «магические» зависимости, дубли схем и ручные костыли там, где должны работать слои приложения.

— Тяжелую логику пихают в path operation. Эндпоинт должен принимать запрос и отдавать ответ, а не собирать бизнес-процесс.
— Смешивают Pydantic-модели для входа, ответа и внутреннего домена. В итоге любое изменение тянет цепочку правок по всему коду.
— Не выносят работу с БД в отдельный слой. Когда ORM живет прямо в роуте, тесты и рефакторинг превращаются в ремонт на ходу.
— Злоупотребляют Depends. Если зависимость делает больше, чем внедрение сервиса или сессии, это уже скрытая бизнес-логика.

Еще одна типовая проблема — отсутствие явных границ между API, сервисами и инфраструктурой. Пока проект маленький, это не мешает. Потом любой новый сценарий начинает ломать старые ручки, потому что все связано со всем.

Если держать роуты тонкими, модели раздельными, а БД и внешние сервисы изолировать за интерфейсами, FastAPI остается быстрым не только в запросах, но и в разработке.
Pydantic ломается не на валидации, а на неаккуратной схеме данных

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

Три правила, которые экономят часы:
— не смешивайте «как пришло» и «как храню» в одной модели;
— для внешнего JSON держите отдельный слой, а внутренние объекты делайте уже нормализованными;
— сложные поля собирайте через field_validator или model_validator, а не через ручной if по всему коду.

Если модель начинает разрастаться, смотрите на признаки:
• один и тот же класс используется для request, response и ORM;
• часть полей нужна только для админки;
• валидация зависит от комбинации нескольких значений.
В такой точке лучше разделить схемы на маленькие: входная, выходная, общая база, отдельный DTO для редких кейсов.

Ещё одна типовая ошибка — пытаться сделать Pydantic «магией для всего». Он хорош там, где нужно явно описать контракт, а не скрыть бизнес-логику. Чем меньше неявности в схеме, тем проще тесты, автодоки и рефакторинг. Плохая модель почти всегда дороже плохого SQL.
5 Django-ошибок, которые ломают проект не в коде, а в архитектуре

Django часто ругают за «магии», но в реальности проблемы обычно в том, как проект собран. Самые дорогие ошибки повторяются из репы в репу: один большой app, смешанные домены, и модели, которые знают слишком много о внешнем мире.

— Ставить всё в один app. Потом сложно выделить платежи, пользователей, каталог и интеграции без боли.
— Тянуть бизнес-логику в views. В итоге тесты хрупкие, а повторное использование почти нулевое.
— Делать модели жирными, но без границ: `save()`, сигналы, кэш, внешние запросы — всё в одном месте.
— Игнорировать сервисный слой. Когда появляется фоноваая задача или API-метод, код начинают копировать.

Рабочее правило простое: model хранит состояние, service — правила, view — вход и выход. Если в сервисе уже есть 200 строк, это не повод «добавить ещё чуть-чуть», а сигнал резать на сценарии и выделять зависимости.

Ещё один маркер зрелости — тестируемость. Если бизнес-поток нельзя прогнать без HTTP и базы, архитектура уже перепутала уровни. Для Django это особенно заметно на проектах, где быстро растут интеграции и админка.

Чем раньше проект разделён по ответственности, тем дешевле потом добавлять фичи, очереди и API без переписывания половины кода.