Легкий путь в Python
5.8K subscribers
142 photos
22 videos
3 files
180 links
Я Алексей Яковенко, senior-разработчик Python. Здесь вы найдете статьи, заметки, посты и видео для прокачки навыков программирования. Интересно и новичку, и профи 💡

По вопросам: https://t.me/yakvenalexx
Download Telegram
Карьерный буст, робот в подарок и призовой фонд 7 500 000 рублей 🤖
Успей зарегистрироваться до 20 октября.


Все это ждет участников трека «Программирование роботов» на всероссийском ИТ-чемпионате МТС True Tech Champ 2025. Присоединяйся, если пишешь на С++, Go, Python, JS, Java, C# или другом языке.

Соревнования пройдут в командах от 2 до 4 человек в несколько этапов:

Квалификация. Тебе предстоит запрограммировать робота на прохождение виртуального лабиринта.
Полуфинал. Ты будешь дистанционно управлять роботом на офлайн-полигоне и наблюдать за его перемещениями в трансляции.
Финал. За две недели до финала организаторы отправят тебе настоящего робота для кастомизации. Ты сможешь модифицировать его, чтобы он оказался быстрее других в многоуровневом офлайн-лабиринте и смог выбить соперников с платформы в шоу-битве.

Команды финалистов получат по одному роботу Waveshare Cobra Flex в подарок и сразятся за крупные денежные призы: 4 000 000 ₽ за первое место, 2 500 000 ₽ за второе и 1 000 000 ₽ за третье.

Еще ты сможешь:

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

📍 Финал состоится 21 ноября в МТС Live Холл в Москве.
👉🏻 Регистрируйся на сайте до 20 октября.
👍96🔥4🤡3🫡3👎1🥰1🤮1👌1💯1
Мой боевой набор MCP-серверов для работы с AI

Делюсь инструментами, которые реально меняют подход к разработке с нейросетями. Использую их и в личных проектах, и в связке с агентами вроде Claude Code или Cursor.

Что такое MCP и почему это важно

Model Context Protocol — это протокол, который даёт AI-ассистенту прямой доступ к вашим инструментам: файловой системе, базам данных, git-репозиториям и API. Вместо бесконечного копипаста нейросеть сама читает код, выполняет запросы к БД и коммитит изменения.

Пять серверов, которые я настраиваю в каждом проекте

1. Filesystem — фундамент работы

"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/путь/к/вашему/проекту"
]
}


Зачем нужен: AI получает доступ к файлам проекта — может читать код, анализировать структуру, вносить изменения. Это базовый инструмент, без которого остальное не имеет смысла. Особенно актуальный инструмент в работе с собственными ии-проектами.

Совет: указывайте путь к корню конкретного проекта, а не к домашней директории. Это и безопаснее, и помогает AI сфокусироваться на релевантных файах.

2. Git — версионирование на автопилоте

"git": {
"type": "stdio",
"command": "uvx",
"args": [
"mcp-server-git",
"--repository",
"/путь/к/вашему/проекту"
]
}


Зачем нужен: AI может изучать историю коммитов, создавать ветки, делать коммиты. Особенно полезно для code review и анализа того, как менялся код со временем.

Требования: нужен Python и установленный uvx.

3. Postgres — работа с БД без головной боли

"postgres": {
"command": "uv",
"args": ["run", "postgres-mcp", "--access-mode=unrestricted"],
"env": {
"DATABASE_URI": "postgresql://user:password@localhost:5432/dbname"
}
}


Зачем нужен: AI может выполнять SQL-запросы, анализировать схему базы данных, помогать с миграциями. Экономит массу времени на отладке запросов и оптимизации.

Важно:
- Флаг --access-mode=unrestricted используйте только в dev-окружении
- Никогда не коммитьте реальные пароли в конфиг — используйте переменные окружения

4. cURL — свобода работы с API

"curl": {
"command": "npx",
"args": ["-y", "@mcp-get-community/server-curl"]
}


Зачем нужен: AI может делать HTTP-запросы к любым API. Тестирование эндпоинтов, интеграция с внешними сервисами — всё через простое текстовое описание задачи.

5. Context7 — актуальная документация библиотек

"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"env": {
"CONTEXT7_API_KEY": "ваш_api_ключ"
}
}


Зачем нужен: даёт AI доступ к актуальной документации популярных библиотек и фреймворков. Вместо того чтобы полагаться на устаревшие знания из обучающей выборки, нейросеть получает свежую информацию об API, best practices и изменениях в новых версиях. Особенно критично для быстро развивающихся экосистем вроде React, Next.js или FastAPI.

API-ключ: получить можно на Сontext7

Как это работает в реальной жизни

Мой типичный workflow выглядит так:

1. Filesystem + Git — AI читает код, вносит изменения, коммитит их с осмысленными сообщениями
2. Postgres — проверяю и оптимизирую SQL-запросы, анализирую данные
3. cURL — тестирую API endpoints прямо в диалоге с AI
4. Context7 — AI работает с актуальной документацией библиотек, не галлюцинирует устаревшие методы

Безопасность превыше всего

Несколько правил, которых я строго придерживаюсь:

- Никогда не давайте AI доступ к продакшн-базам данных
- Создавайте отдельного пользователя БД с минимально необходимыми правами
- Храните секреты и пароли в переменных окружения, а не в конфигах
- Всегда ревьюте действия AI, особенно git-коммиты и изменения в БД

Эти пять MCP-серверов покрывают около 90% моих задач при работе с AI в проектах. Настраиваются один раз, работают везде. AI получает все необходимые инструменты для реальной работы — не просто генерации кода, а полноценного участия в разработке.

Какие MCP-серверы используете вы? Поделитесь опытом в комментариях! 👇
2👍5517🔥10🎉2🙏1🐳1🏆1😘1
А что, GitHub тоже отказался работать?
5😱3🤯2🤗2🤩1😭1
Привет, друзья!

Хочу признаться: последние пару месяцев я немного выпал из привычного ритма. Сначала — работа над крупным государственным проектом, потом отпуск, а затем и небольшая болезнь. В итоге образовалась пауза, и я упустил момент, когда многие из вас активно росли и развивались внутри сообщества.

Но теперь я снова в строю! Уже в эти выходные выйду с новым материалом — и дальше постараюсь не исчезать надолго.

Спасибо, что остаётесь рядом и продолжаете двигаться вперёд ❤️
Please open Telegram to view this post
VIEW IN TELEGRAM
277🔥30👍17👏4👌2🤡2😎2🥰1
Лайфхак: обходим CORS через прокси-бэкенд на Python 🐍

Недавно у меня был забавный случай. Работал с фронтендером над одним проектом, и он столкнулся с классической проблемой CORS. Вместо того чтобы разбираться с настройками, он просто поднял свой прокси-сервер на Node.js, который пробрасывает запросы к моему Python API. Проблема решена за 15 минут.

Я подумал — а почему бы не показать, как сделать то же самое на Python? Получится еще быстрее и элегантнее.

Что такое CORS и почему он мешает?

CORS (Cross-Origin Resource Sharing) — это механизм безопасности браузера. Он блокирует запросы с одного домена на другой.

Пример: Ваш фронтенд крутится на localhost:3000, а API находится на api.example.com. Браузер видит разные origins и блокирует запрос. В консоли вы видите знакомую ошибку:

Access to fetch at 'https://api.example.com' from origin 'http://localhost:3000' 
has been blocked by CORS policy


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

Решение: прокси-бэкенд

Идея простая: поднимаем свой легкий сервер, который:

1. Принимает запросы от фронта (один и тот же origin — никаких CORS)
2. Пробрасывает их на целевой API
3. Возвращает ответ обратно фронту

Для браузера это обычный запрос на свой сервер. Для API — запрос с бэкенда (где CORS не существует).

Реализация на FastAPI

from fastapi import FastAPI, Request, Response
from fastapi.middleware.cors import CORSMiddleware
import httpx

app = FastAPI()

# Разрешаем CORS для фронта
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_methods=["*"],
allow_headers=["*"],
)

TARGET_API = "https://api.example.com"

@app.api_route("/{path:path}", methods=["GET", "POST", "PUT", "DELETE", "PATCH"])
async def proxy(path: str, request: Request):
# Формируем URL целевого API
url = f"{TARGET_API}/{path}"

# Получаем тело запроса
body = await request.body()

# Пробрасываем запрос
async with httpx.AsyncClient() as client:
response = await client.request(
method=request.method,
url=url,
headers=dict(request.headers),
content=body,
params=request.query_params
)

# Возвращаем ответ фронту
return Response(
content=response.content,
status_code=response.status_code,
headers=dict(response.headers)
)


Запуск:
pip install fastapi httpx uvicorn
uvicorn main:app --reload --port 8000


Теперь ваш фронт делает запросы на localhost:8000, а прокси пробрасывает их куда нужно.

Вариант на Flask (для минималистов)

from flask import Flask, request, Response
from flask_cors import CORS
import requests

app = Flask(__name__)
CORS(app)

TARGET_API = "https://api.example.com"

@app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE', 'PATCH'])
def proxy(path):
url = f"{TARGET_API}/{path}"

response = requests.request(
method=request.method,
url=url,
headers={k: v for k, v in request.headers if k != 'Host'},
data=request.get_data(),
params=request.args
)

return Response(
response.content,
status=response.status_code,
headers=dict(response.headers)
)

if __name__ == '__main__':
app.run(port=8000, debug=True)


Когда это полезно?

В разработке — когда нет доступа к настройкам целевого API
Сторонние API — многие публичные API не поддерживают CORS
Дополнительная логика — можно добавить кэширование, логирование, rate limiting
Скрытие API ключей — не светите токены на фронте
Когда хочется прикрутить стороннее API напрямую к своему фронту, а API не позволяет (например API Ozon Seller с недавнего времени)

Вот так простая проблема с CORS решается за 10 минут с помощью Python. А фронтендеры могут спокойно работать дальше, не копаясь в настройках😉

Кстати, если у вас есть интересные кейсы из практики — пишите в комментарии, разберем вместе!
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥36👍1593🕊1🫡1
Возвращаюсь к практике с LangGraph! 🎯

Многие из вас ждали продолжения серии статей про LangChain и LangGraph — я не забыл о ней, просто последние пару месяцев совсем не было времени на публикации.

Сейчас возвращаюсь, и осталась последняя, самая практическая часть. Долго думал над форматом — хотелось найти что-то реально интересное, не просто очередной RAG-чатбот или скрипт для парсинга новостей.

И вот что решил сделать:

Телеграм-бот с детективной игрой, где вы — следователь, расследующий преступление. Агент на LangGraph генерирует уникальное дело: подозреваемые, улики, алиби, мотивы. Вы осматриваете локации, допрашиваете свидетелей, собираете доказательства. Все это в свободной форме — никаких готовых вариантов ответов, только живое общение с ИИ.

Что интересного покажу:
- ReAct агент в деле — как он логически рассуждает от лица разных персонажей
- Граф состояний — обработка разных типов действий игрока
- Сложный State менеджмент — агент помнит всю картину преступления, показания, улики
- Условную логику — персонажи меняют поведение в зависимости от ваших вопросов и улик
- Интеграцию с Telegram Bot API

Это будет полноценное приложение, которое можно запустить и поиграть. Весь код, естественно, будет в статье.

Готовлю материал, выйдет на следующей неделе. Кто ждал практики — она будет 🔥
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥100👍22❤‍🔥9🤩32💯2🙉1
Многие начинающие разработчики, которые уже пишут свои программы, рано или поздно приходят к понятию деплоя. К сожалению, часто в проектах, в которых нам приходится участвовать, нет DevOps-специалиста, поэтому ответственность за деплой ложится на нас.

Этот пост я хочу посвятить новичкам, у которых вызывает трепет задача запуска приложения на сервере.

Нужно понимать одну важную вещь: в абсолютном большинстве случаев вы будете работать с готовой операционной системой. Обычно это какой-то дистрибутив Linux (часто Ubuntu) или Windows Server, но с одним критическим отличием — там не будет графической оболочки. Мышкой некуда будет нажать.

В остальном же у вас не вызывает трепет взаимодействие с операционной системой, на которой вы работаете, верно? Вот и сервер — это та же самая операционная система, только без GUI. Файлы, процессы, сеть — все это работает точно так же.

Единственное, что меняется — способ взаимодействия. Вместо мышки у вас будет SSH и командная строка. Вместо двойного клика — команды типа python app.py или systemctl start myapp. Это не магия, это просто другой интерфейс для той же самой системы.

Так что не бойтесь серверов. Просто держите крышку открытой 😄

P.S. Рассказать в следующих постах про основные способы запуска Python приложений на VPS-сервере?
👍11116❤‍🔥5🔥5😁4🐳1💯1💋1🙈1
🧩 Одно ядро авторизации и куча микросервисов на FastAPI

Простая и надёжная схема, которую можно масштабировать хоть до бесконечности

Сегодня расскажу, как вокруг одного ядра авторизации можно выстраивать десятки микросервисов — лёгких, быстрых и независимых. Вся магия держится на правильной работе с access и refresh токенами. На самом деле всё гораздо проще, чем кажется.

🔐 Как работает мини-бэкенд (микросервис)

Каждый микросервис получает в запросах заголовок:

Authorization: Bearer <access_token>


И делает всего одну вещь — локально проверяет access_token через PyJWT:

- подпись валидна ✔️
- exp не истёк ✔️
- формат корректный ✔️

Если всё ок → выполняет свою бизнес-логику.
Если токен умер → просто отдаёт 401 Unauthorized.

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

👉 На этом его роль заканчивается. Микросервис никогда не работает с refresh токенами, не хранит их и не обновляет.

🖥 Что делает фронтенд при ошибке 401

Вот здесь происходит самая приятная магия:

1. Фронт получает 401 → понимает “access токен умер”.
2. Достаёт у себя в хранилище refresh_token.
3. Идёт в Auth Service: POST /auth/refresh.
4. Получает свежую пару access + refresh.
5. Сохраняет.
6. Повторяет оригинальный запрос уже с новым access токеном.
7. Микросервис снова проверяет токен → всё работает.

Микросервисы остаются лёгкими, а ядро авторизации — централизованным и контролирующим.

👤 Как выглядит флоу регистрации / авторизации

1. Пользователь вводит почту.
2. Бэк проверяет:
– если пользователя нет → запускается сценарий регистрации (отправляется временный пароль);
– если есть → открывается форма ввода пароля.
3. При успешном входе бэк отдаёт фронту два токена:

- access (живёт ~15 минут)
- refresh (живёт, например, 3 дня)

В бою именно фронтенд хранит оба токена. Это важно.

🤝 Взаимодействие микросервисов с ядром

Микросервис:

- видит только access_token
- проверяет его валидность
- при успехе получает из токена базовые данные пользователя
- при провале отдаёт 401

Если приходит новый пользователь — делается хук: микросервис принимает токен + почту и фиксирует у себя пользователя под своим айди. Из токена через валидатор извлекается айди пользователя и происходит фиксация пользователя в своей системе. Ключевая связка тут - свой айди + основной айдишник пользователя.

Частые вопросы

Нужно ли хранить refresh_token в микросервисе?
Нет. Только фронт.

Что делать, если access токен истёк?
Вернуть 401. Фронт сам всё обновит.

Можно ли доверять данным из JWT?
Да, если подпись валидна — данные не были изменены.

🚀 Масштабируемость и лучшие практики

- Такая схема одинаково отлично работает и для веба, и для мобильных приложений.
- Можно добавлять авторизацию через Google / GitHub — механика почти та же: там тоже возвращаются access + refresh токены.
- При желании refresh токен можно убирать в защищённую cookie — это уже уровень “best practices 2.0”.

🔮 Немного про магию QR-кодов

То, что кажется “инопланетной технологией”, например авторизация через QR (как в VK), на самом деле очень просто:

QR-код содержит ссылку с параметрами (токены, коды, состояния).
Фронт её парсит → бэк это фиксирует → выдаются токены.

Никаких чудес — просто длинная URL-строка с зашитыми данными 😄

🧠 Итог

Вся система строится вокруг простого, но мощного принципа:

> Ядро авторизации выдаёт токены.
> Микросервисы проверяют access и ничего больше не знают.
> Фронтенд управляет жизненным циклом токенов.


Именно такая архитектура позволяет легко строить вокруг ядра десятки сервисов, не городя сложные и тяжёлые схемы.

P.S. Рассказать в одном из следующих постов почему refresh token нужно хранить в защищенной кукки сессии и как вообще это работает?
1👍6912❤‍🔥5🔥5🎉2😇1🤝1👾1
Как легко создать и накатить дамп базы данных PostgreSQL

Сегодня разберем простую, но важную тему — работа с дампами PostgreSQL. Это нужно для бэкапов, переноса данных между окружениями или клонирования prod в dev.

⚙️Установка psql

Linux (Ubuntu/Debian):
sudo apt update
sudo apt install postgresql-client


macOS:
brew install postgresql


Windows:

1. Скачайте PostgreSQL с https://www.postgresql.org/download/windows/
2. При установке выберите "Command Line Tools"
3. Добавьте в PATH: C:\Program Files\PostgreSQL\16\bin

Проверка установки (все ОС):
psql --version


☝️ Важно: версия psql должна совпадать или быть новее версии вашего PostgreSQL сервера.

💾 Создание дампа (бэкап)

Linux/macOS:
# Базовая команда
pg_dump -h localhost -p 5432 -U postgres -d mydb > dump.sql

# Без запроса пароля
PGPASSWORD=your_password pg_dump -h localhost -p 5432 -U postgres -d mydb > dump.sql

# С сжатием (для больших баз)
pg_dump -h localhost -p 5432 -U postgres -d mydb | gzip > dump.sql.gz


Windows (CMD):
REM Базовая команда
pg_dump -h localhost -p 5432 -U postgres -d mydb > dump.sql

REM Без запроса пароля
set PGPASSWORD=your_password
pg_dump -h localhost -p 5432 -U postgres -d mydb > dump.sql


Windows (PowerShell):
# Без запроса пароля
$env:PGPASSWORD="your_password"
pg_dump -h localhost -p 5432 -U postgres -d mydb > dump.sql


Параметры команды:
- -h — хост (localhost или IP сервера)
- -p — порт (по умолчанию 5432)
- -U — пользователь
- -d — название базы данных

📥 Заливка дампа (восстановление)

Linux/macOS:
# Из обычного дампа
psql -h localhost -p 5432 -U postgres -d mydb -f dump.sql

# Без запроса пароля
PGPASSWORD=your_password psql -h localhost -p 5432 -U postgres -d mydb -f dump.sql

# Из сжатого дампа
gunzip < dump.sql.gz | psql -h localhost -p 5432 -U postgres -d mydb


Windows (CMD):
REM Из обычного дампа
set PGPASSWORD=your_password
psql -h localhost -p 5432 -U postgres -d mydb -f dump.sql


Windows (PowerShell):
$env:PGPASSWORD="your_password"
psql -h localhost -p 5432 -U postgres -d mydb -f dump.sql


🐳Работа с Docker (универсально для всех ОС)

Если PostgreSQL крутится в Docker, команды одинаковые на всех платформах:

# Создание дампа
docker exec -t postgres_container pg_dump -U postgres -d mydb > dump.sql

# Заливка дампа
docker exec -i postgres_container psql -U postgres -d mydb < dump.sql


Или через docker-compose:

# Создание
docker-compose exec -T db pg_dump -U postgres -d mydb > dump.sql

# Заливка
docker-compose exec -T db psql -U postgres -d mydb < dump.sql


🔐 Лайфхак: файл для автоматической аутентификации

Linux/macOS:
# Создаем файл
nano ~/.pgpass

# Добавляем строку (формат: host:port:database:username:password)
localhost:5432:*:postgres:your_password

# Ставим права
chmod 600 ~/.pgpass


Windows:

Создайте файл %APPDATA%\postgresql\pgpass.conf со строкой:
localhost:5432:*:postgres:your_password


Теперь команды работают без пароля на всех платформах!

🛠 Полезные опции pg_dump

# Только структура (без данных)
pg_dump -s -h localhost -U postgres -d mydb > schema.sql

# Только данные (без структуры)
pg_dump -a -h localhost -U postgres -d mydb > data.sql

# Конкретная таблица
pg_dump -t users -h localhost -U postgres -d mydb > users.sql

# Исключить таблицу
pg_dump --exclude-table=logs -h localhost -U postgres -d mydb > dump.sql

# Verbose режим (показывает процесс)
pg_dump -v -h localhost -U postgres -d mydb > dump.sql


⚠️ Типичные ошибки

`pg_dump: error: server version mismatch`
→ Обновите postgresql-client до версии вашего сервера

`psql: FATAL: password authentication failed`
→ Проверьте пароль или используйте PGPASSWORD / pgpass файл

`permission denied`
→ Проверьте права на файл дампа

`command not found` (Windows)
→ Добавьте путь к PostgreSQL в PATH

📝 Резюме

✔️Установили postgresql-client (Linux/Mac) или PostgreSQL Tools (Windows)
✔️Создаем дамп: pg_dump ... > dump.sql
✔️Накатываем дамп: psql ... -f dump.sql
✔️Для Docker используем docker exec (работает везде одинаково)
✔️Настраиваем .pgpass / pgpass.conf для удобства

Просто, быстро, надежно — на любой платформе! 🚀

Есть вопросы? Пишите в комментариях👇
Please open Telegram to view this post
VIEW IN TELEGRAM
❤‍🔥26🔥1911🫡21💋1🙉1
🎯 Как я перегнал 30 ГБ картинок через Google Drive, не имея SSH — и почему Python снова спас день

Иногда жизнь подкидывает нетривиальные задачи. Например: нужно сгенерировать ~100 000 изображений (≈30 ГБ) и доставить их на боевой VPS, до которого… нет прямого SSH-доступа.
VPN поднимать лень, корпоративная сеть всё режет, облачные сториджи не выделены.
Но есть Python, немного смекалки — и Google Drive c 10 ГБ свободного места.

Вот как это было 👇

🔥 Этап 1 — Генерация 100 000 баннеров

Надо было быстро нагенерить огромный массив картинок по CSV.
Pillow + ThreadPoolExecutor → и мощный арендованный сервер выдаёт за ~20 минут набор изображений общим весом около 30 ГБ.

Локальная машина такую нагрузку просто не вывезла бы — а на удалённой всё прошло гладко.

🔥 Этап 2 — Как перенести 30 ГБ, когда SSH недоступен

И вот тут началось самое интересное.

Что имеем:

прямой SSH заблокирован корпоративной сетью
не хочется поднимать временный VPN/туннель
не хочется разворачивать MinIO, S3 или ещё что-то тяжёлое под одноразовую задачу
✔️ есть Google Drive с 10 ГБ свободного места
✔️ и Python на VPS

Задача — доставить 30 ГБ на VPS, не превышая лимит доступного облака.

💡 Решение — многотомный ZIP + gdown

На Windows-сервере упаковал результаты в многотомный архив WinRAR:

all_images.z01  
all_images.z02
all_images.z03
...
all_images.zip


Каждый том ≤10 ГБ — чтобы влазил в Google Drive.

🔥 Этап 3 — Python-скрипт на VPS, который «вытягивает» файлы из Google Drive

На VPS создал виртуальное окружение и установил gdown:

python -m venv .venv
source .venv/bin/activate
pip install gdown


Мини-скрипт gdrive_download.py:

import sys
import gdown

def main():
if len(sys.argv) != 3:
print("Usage: python gdrive_download.py <share_url> <output_name>")
sys.exit(1)

url = sys.argv[1]
output = sys.argv[2]

gdown.download(url=url, output=output, fuzzy=True)

if __name__ == "__main__":
main()


fuzzy=True позволяет передавать обычную share-ссылку формата:

https://drive.google.com/file/d/<ID>/view?usp=sharing


🔥 Этап 4 — Гениальное по простоте: в облаке хранится только ОДИН файл

Дальше пошёл цикл:

1️⃣ заливаю на Google Drive all_images.z01
2️⃣ копирую share-ссылку
3️⃣ на VPS качаю том:

python gdrive_download.py "https://drive.google.com/file/d/FILE_ID/view?usp=sharing" all_images.z01


4️⃣ проверяю размер:

ls -lh all_images.z01


5️⃣ удаляю файл из Drive → освобождаю место → загружаю следующий том

Так все части многотомного архива оказываются на VPS, а в облаке в каждый момент времени лежит только один файл.

🔥 Этап 5 — Магия unzip: один ZIP — вся директория

Когда все тома были скачаны:

unzip all_images.zip


unzip автоматически подтянул все .z0N части и развернул структуру.

Дальше:

find extracted_folder -type f -name "*.jpg" -exec mv {} /var/www/photos/ \;


Nginx уже раздавал файлы как обычную статику — и вот у меня есть новый распределённый узел с 100 000 изображений, доступный глобально по прямым ссылкам.

⚡️ Итог

Что было нужно?

- Python
- gdown
- WinRAR
- Google Drive
- немного инженерной смекалки

Что получилось?

30 ГБ данных ушли на VPS через Drive без SSH, VPN и сложных настройкок
— Всего за один проход
— С полностью автоматизированным мини-скриптом

🎬 Мораль истории

Если у вас есть Python — значит, у вас есть способ решить почти любую инженерную задачу. Даже если корпоративная сеть пытается вам помешать 😉
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥32👍108👏3👌2😍21🤔1🤗1
🐍 Что такое аргументы при запуске Python-скриптов и зачем они вообще нужны?

Когда мы запускаем Python-скрипт, нам часто нужно передать ему какие-то настройки: диапазоны, файлы, коэффициенты, флаги и т. д.
Чтобы не хардкодить всё прямо в коде, Python позволяет передавать параметры снаружи — через аргументы командной строки.

Проще говоря: вместо того чтобы переписывать переменные в .py файле, мы даём скрипту команды прямо при запуске.

Например:

python script.py --name "Ozon" --delay 5 --enable-log


Такой подход даёт 3 плюса:

1. Гибкость — один и тот же скрипт работает в разных режимах.
2. Удобство — не надо лазить в код ради одного числа.
3. Автоматизация — идеально для cron, CI/CD и массовых операций.

📦 Практический пример

Вот как это делается с помощью библиотеки argparse:

import argparse


def parse_arguments():
parser = argparse.ArgumentParser(
description="Пример использования аргументов"
)

parser.add_argument(
"--start",
type=int,
required=True,
help="Начальный индекс"
)

parser.add_argument(
"--end",
type=int,
required=True,
help="Конечный индекс"
)

parser.add_argument(
"--markup",
type=float,
default=10.0,
help="Процент наценки"
)

return parser.parse_args()


if __name__ == "__main__":
args = parse_arguments()
print(f"Обрабатываю товары от {args.start} до {args.end} с наценкой {args.markup}%")


Запуск:

python update_prices.py --start 0 --end 17 --markup 15


Вывод:

Обрабатываю товары от 0 до 17 с наценкой 15%
👍287🔥4🎉2👎1🐳1👨‍💻1🎃1
Приятно, конечно, но немного смущает, что нейронка уровня Claude дает мне советы о том, как атаковать сайт🤔
Please open Telegram to view this post
VIEW IN TELEGRAM
😁44🤣12😱4🤨2👾21👍1🔥1👌1
🚀 Как поднять лояльность магазина на Авито до 100% с Python

Интегрировал Avito Messenger API и настроил автоматические уведомления в Telegram. Результат — покупатели получают ответы моментально, лояльность 100%. Сейчас расскажу, как реализовать это на Python асинхронно.

📦 Стек технологий
pip install fastapi uvicorn aiohttp python-dotenv


💻 Решение за 2 шага

Шаг 1: Регистрируем webhook

import asyncio
import aiohttp
import os
from dotenv import load_dotenv

load_dotenv()

async def get_token():
url = "https://api.avito.ru/token/"
data = {
"grant_type": "client_credentials",
"client_id": os.getenv("AVITO_CLIENT_ID"),
"client_secret": os.getenv("AVITO_CLIENT_SECRET"),
}
async with aiohttp.ClientSession() as session:
async with session.post(url, data=data) as resp:
return (await resp.json())["access_token"]

async def register_webhook(webhook_url):
token = await get_token()
url = "https://api.avito.ru/messenger/v3/webhook"
headers = {"Authorization": f"Bearer {token}"}

async with aiohttp.ClientSession() as session:
async with session.post(url, json={"url": webhook_url}, headers=headers) as resp:
print(f" Webhook зарегистрирован: {resp.status}")

asyncio.run(register_webhook("https://your-domain.ru/webhook/avito"))


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

Шаг 2: FastAPI обработчик

from fastapi import FastAPI, Request
import aiohttp
from datetime import datetime
import os

app = FastAPI()

TOKEN = os.getenv("TELEGRAM_BOT_TOKEN")
CHAT_ID = os.getenv("TELEGRAM_CHAT_ID")

async def send_telegram(text: str):
url = f"https://api.telegram.org/bot{TOKEN}/sendMessage"
async with aiohttp.ClientSession() as session:
await session.post(url, json={"chat_id": CHAT_ID, "text": text})

@app.post("/webhook/avito")
async def webhook(request: Request):
data = await request.json()
payload = data.get("payload", {})

if payload.get("type") == "message":
value = payload["value"]
msg = value["content"]["text"]
author = value["author_id"]
time = datetime.fromtimestamp(value["created"]).strftime("%H:%M")

notification = f"📨 Новое сообщение\n\n💬 {msg}\n👤 {author}\n {time}"
await send_telegram(notification)

return {"status": "ok"}

@app.get("/health")
async def health():
return {"status": "healthy"}


Запуск:
uvicorn main:app --host 0.0.0.0 --port 5000


🔑 .env файл

AVITO_CLIENT_ID=your_id
AVITO_CLIENT_SECRET=your_secret
TELEGRAM_BOT_TOKEN=your_token
TELEGRAM_CHAT_ID=your_chat_id


📈 Результат

⚡️ Асинхронная обработка — нет блокировок
📱 Моментальные уведомления в Telegram
🎯 Лояльность магазина 100%
⏱️ Ответы за минуты вместо часов
🚀 Высокая производительность FastAPI

💡 Как работает:

1. Регистрируешь webhook один раз через async скрипт
2. Avito шлёт POST-запросы при новых сообщениях
3. FastAPI асинхронно обрабатывает и пересылает в Telegram
4. Все запросы неблокирующие — высокая пропускная способность

Чистая асинхронная архитектура без polling и блокировок! 🔥

Вопросы? Пишите 👇
🔥38👍1551😍1💋1🎃1
Быстрый вход по SSH без пароля за пару минут

Настроим автоматический вход по SSH-ключу с переходом в root. Вместо ввода паролей будете просто писать ssh myserver и сразу попадать в root-сессию.

Полный скрипт для настройки

Просто подставьте свои данные и выполните:

Linux/MacOS

# Задаём переменные
ALIAS_NAME=myserver
HOST=1.222.33.44
PORT=22
USER=username

# Генерируем ключ
mkdir -p "$HOME/.ssh/project_keys/$ALIAS_NAME" && \
ssh-keygen -t ed25519 -f "$HOME/.ssh/project_keys/$ALIAS_NAME/id_ed25519"

# Копируем на сервер (один раз введёте пароль)
ssh-copy-id -i "$HOME/.ssh/project_keys/$ALIAS_NAME/id_ed25519.pub" -p "$PORT" "$USER@$HOST"

# Настраиваем конфиг
KEY_PATH="$HOME/.ssh/project_keys/$ALIAS_NAME/id_ed25519"
cat >> "$HOME/.ssh/config" <<EOF
Host $ALIAS_NAME
HostName $HOST
Port $PORT
User $USER
IdentityFile $KEY_PATH
RemoteCommand sudo -i
RequestTTY yes
EOF
chmod 600 "$HOME/.ssh/config"


Windows (PowerShell)

# Задаём переменные
$ALIAS_NAME = "myserver"
$HOST = "1.222.33.44"
$PORT = "22"
$USER = "username"

# Генерируем ключ
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.ssh\project_keys\$ALIAS_NAME" | Out-Null
ssh-keygen -t ed25519 -f "$env:USERPROFILE\.ssh\project_keys\$ALIAS_NAME\id_ed25519"

# Копируем на сервер
type "$env:USERPROFILE\.ssh\project_keys\$ALIAS_NAME\id_ed25519.pub" | ssh -p $PORT "$USER@$HOST" "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

# Настраиваем конфиг
$KEY_PATH = "$env:USERPROFILE\.ssh\project_keys\$ALIAS_NAME\id_ed25519"
@"

Host $ALIAS_NAME
HostName $HOST
Port $PORT
User $USER
IdentityFile $KEY_PATH
RemoteCommand sudo -i
RequestTTY yes
"@ | Add-Content "$env:USERPROFILE\.ssh\config"


Опционально: sudo без пароля

Если всё равно запрашивается пароль для sudo, на сервере под root:

visudo
# Добавить: username ALL=(ALL:ALL) NOPASSWD:ALL


Готово!

Теперь подключаемся просто:
ssh myserver


Для нескольких серверов повторите с другими переменными:
ssh production
ssh staging
ssh backup


Безопасность: Храните ключи в безопасности, используйте отдельный ключ для каждого сервера, на production лучше ограничить sudo конкретными командами.
18🔥15👍6❤‍🔥33👎1🥰1💯1
Привет, друзья!
Пришел вас порадовать, если вы вдруг хотите перед новым годом прокачаться в темах аутентификации и кэширования.
 
В школе Python разработки Pytex на этой неделе проходят 2 практических вебинара с Senior-разработчиком Артёмом Шумейко. 

16 декабря в 18:00 МСК — «Пишем систему аутентификации и авторизации: сессии vs JWT токены»
На вебинар вы:
— разберётесь в ключевых принципах аутентификации и авторизации через сессии и токены
— вместе с Senior-разработчиком напишете приложение, в котором реализуете оба подхода.
После такой пошаговой практики вы будете понимать, как строить безопасную систему входа в приложение.  

РЕГИСТРИРУЙТЕСЬ НА ВЕБИНАР ПО АУТЕНТИФИКАЦИИ 

18 декабря в 18:00 МСК — «5 слоёв кэширования в веб-приложениях»
На вебинаре вы:
— разберёте теорию кэширования: уровни, механизмы, типы хранилищ;
— поймёте, где и зачем применять разные виды кэша;
— разберетесь, как бэкендер может снизить нагрузку на бэк в десятки раз через кэширование на уровне браузера;
— на практике внедрите 5 уровней кэширования в реальное приложение.
Это тот навык, который отличает джуна от мидла и который особенно ценят работодатели.

РЕГИСТРИРУЙТЕСЬ НА ВЕБИНАР ПО КЭШИРОВАНИЮ

Это абсолютно бесплатно, поэтому регистрируйтесь и качайте харды перед праздниками⬆️
🔥149👍72👎1🥰1🤮1😍1
Claude не перестает поражать своей непосредственностью😆
🤣41😁10🔥3💋1😇1🎄1
Как всегда запускать Docker Compose плагин, даже если в скриптах или Makefile используется старая команда

Многие проекты используют Makefile или скрипты с командой docker-compose. Однако в современных системах Docker Compose часто устанавливается как плагин и вызывается через docker compose. Это приводит к ошибкам или неработоспособности старых скриптов, если не предпринять дополнительных действий.

Решение

Создайте символическую ссылку на Docker Compose плагин, чтобы команда docker-compose всегда запускала нужный плагин.

1. Найдите путь к плагину

Например:

   /usr/libexec/docker/cli-plugins/docker-compose

или для локальной установки:

   ~/.docker/cli-plugins/docker-compose


2. Создайте символическую ссылку

Для системной установки:

   sudo ln -s /usr/libexec/docker/cli-plugins/docker-compose /usr/local/bin/docker-compose

Для пользовательской:

   ln -s ~/.docker/cli-plugins/docker-compose ~/.local/bin/docker-compose

(убедитесь, что ~/.local/bin в PATH).

3. Проверьте работу

   docker-compose --version

Команда должна вывести версию плагина.

Теперь команда docker-compose будет вызывать Docker Compose плагин.
Не нужно менять Makefile или скрипты — всё работает как раньше, а команда docker compose тоже будет доступна.
2👍167🔥5🙈2🤗21👎1👌1🤝1
🎄 Кому нужен .RU-домен за 1 рубль?

В REG.RU сегодня проходит новогодняя акция — можно взять домен в зоне .RU всего за 1 ₽ по промокоду NY2026!

💡 Акция действует только сегодня и завтра, так что лучше не тянуть.

Как получить домен за 1 рубль:

1. Зарегистрируйтесь на reg.ru, если у вас еще нет аккаунта.
2. Перейдите в подбор доменов и выберите желаемое имя.
3. Добавьте домен в корзину.
4. Введите промокод NY2026 и нажмите на «плюсик».
5. Отключите все лишние услуги — хостинг, облако, дополнительные зоны и т. д.
6. Оформите заказ — и ваш домен уходит за 1 ₽ на год!
13👍7🔥7🤮6🙈2❤‍🔥1🎉1👀1
Как автоматизировать Photoshop через кодинг

Когда говорят об автоматизации, чаще всего имеют в виду Python. Но важно понимать: Photoshop не выполняет Python-код напрямую.

Зато у него есть встроенная поддержка скриптов — Photoshop умеет исполнять код на JavaScript (ExtendScript).

Это не «JS как в браузере» и не замена Python. Это родной язык автоматизации Photoshop, с прямым доступом к:

- слоям
- тексту
- смарт-объектам
- экспорту файлов
- истории документа

Если задача — управлять самим Photoshop, то скрипты внутри Photoshop — самый надёжный путь.

Что это даёт на практике

Через код можно:

- массово менять текст в PSD
- генерировать сотни изображений из одного шаблона
- автоматизировать экспорт
- исключить Actions и Variables с их ограничениями

По сути, мы описываем действия, которые дизайнер делает руками, но в виде кода.

Пример задачи

Есть:

- один PSD
- текстовый слой
- значения 1 м → 100 м

Нужно:

- автоматически подставить значения
- сохранить 100 PNG-файлов
- вернуть PSD в исходное состояние

Пример скрипта для Photoshop (JSX)

#target photoshop

var doc = app.activeDocument;
var layerName = "1 м"; // имя текстового слоя
var outputFolder = Folder.selectDialog("Выбери папку для сохранения");

if (!outputFolder) {
alert("Папка не выбрана");
exit();
}

function findTextLayer(layerSet) {
for (var i = 0; i < layerSet.layers.length; i++) {
var layer = layerSet.layers[i];
if (layer.kind == LayerKind.TEXT && layer.name == layerName) {
return layer;
}
if (layer.typename == "LayerSet") {
var found = findTextLayer(layer);
if (found) return found;
}
}
return null;
}

var textLayer = findTextLayer(doc);
if (!textLayer) {
alert("Текстовый слой не найден");
exit();
}

for (var i = 1; i <= 100; i++) {
textLayer.textItem.contents = i + " м";

var file = new File(outputFolder + "/pkabel_4x2_5_" + i + "m.png");

var opts = new PNGSaveOptions();
opts.compression = 9;

doc.saveAs(file, opts, true, Extension.LOWERCASE);
}

// откат без сохранения
doc.activeHistoryState = doc.historyStates[0];

alert("Готово!");


Как запускать

- Photoshop → Файл → Сценарии → Обзор…
- выбрать .jsx
- выбрать папку
- получить пачку файлов

Важный момент

Python здесь не «конкурент» JavaScript.

- Python — отличный оркестратор процессов
- Photoshop — отдельная среда выполнения
- ExtendScript — язык управления внутри неё

В реальных пайплайнах это часто комбинируется: Python → запускает процессы → Photoshop выполняет свои скрипты
🔥145👍5❤‍🔥1🙉1
Бесплатная учительская подписка ChatGPT Plus 🎓

Что такое учительская подписка?

Это специальная образовательная версия ChatGPT Plus с полным доступом к GPT-4, расширенными возможностями и приоритетом в обработке запросов — все бесплатно для преподавателей.

Как получить бесплатно:

1. Переходим по ссылке https://em.bjedu.tech/en/ и создаем бесплатную образовательную почту (обязательно в зоне erzi.me)

2. Копируем полученный email адрес

3. Заходим в ChatGPT: https://chatgpt.com (Обязательно используйте VPN!)

4. Нажимаем "Зарегистрироваться" и вставляем образовательную почту

5. Придумываем надежный пароль и жмем "Продолжить"

6. Копируем код подтверждения из письма и вводим его

7. Заполняем данные регистрации

🎯 Важно: В поле "Роль" обязательно выбираем "Teacher" (Учитель)

8. Если после регистрации видите значок образовательной подписки — поздравляю, все получилось! 🎉
🔥158👍6🍓1🎃1😘1