🚀 DOCKER: МНОГОЭТАПНАЯ СБОРКА И HEALTHCHECKS — ЛИФТ НА СЕНЬОРА!
Привет, будущий Senior! 🧠 Разберем две мощные концепции для эффективного, безопасного и управляемого продакшена.
🎯 МНОГОЭТАПНАЯ СБОРКА
Зачем? Чтобы финальный образ весил 50 МБ вместо 1.5 ГБ! 💪
Решение: Разделяем сборку и запуск на разные этапы (stages) в одном Dockerfile.
Пример для Python:
🔥 HEALTHCHECKS
Healthcheck — встроенный механизм самодиагностики контейнера.
Зачем в Dockerfile?
ВАЖНОЕ РАЗГРАНИЧЕНИЕ:
1. Для Docker / Docker Compose — HEALTHCHECK из Dockerfile работает.
2. Для Kubernetes — HEALTHCHECK ИГНОРИРУЕТСЯ! 🚨 Используются Probes:
• livenessProbe: Проверяет, жив ли контейнер.
• readinessProbe: Проверяет, готов ли принимать трафик.
💎 ИТОГ:
• Multi-stage — must have для прода: меньше размер, выше безопасность.
• Healthchecks — понимай контекст: Dockerfile для standalone, свои probes для K8s.
Сеньор выбирает правильный инструмент для задачи. 👁️🗨️
#Docker #DevOps #SeniorPython
Привет, будущий Senior! 🧠 Разберем две мощные концепции для эффективного, безопасного и управляемого продакшена.
🎯 МНОГОЭТАПНАЯ СБОРКА
Зачем? Чтобы финальный образ весил 50 МБ вместо 1.5 ГБ! 💪
Решение: Разделяем сборку и запуск на разные этапы (stages) в одном Dockerfile.
Пример для Python:
# Этап 1: Сборщик
FROM python:3.11-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN python -m venv /opt/venv \
&& . /opt/venv/bin/activate \
&& pip install --no-cache-dir -r requirements.txt
# Этап 2: Финальный образ
FROM python:3.11-alpine
WORKDIR /app
COPY --from=builder /opt/venv /opt/venv
COPY . .
ENV PATH="/opt/venv/bin:$PATH"
CMD ["python", "app.py"]
🔥 HEALTHCHECKS
Healthcheck — встроенный механизм самодиагностики контейнера.
Зачем в Dockerfile?
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 CMD curl -f http://localhost:8080/health/ || exit 1ВАЖНОЕ РАЗГРАНИЧЕНИЕ:
1. Для Docker / Docker Compose — HEALTHCHECK из Dockerfile работает.
2. Для Kubernetes — HEALTHCHECK ИГНОРИРУЕТСЯ! 🚨 Используются Probes:
• livenessProbe: Проверяет, жив ли контейнер.
• readinessProbe: Проверяет, готов ли принимать трафик.
💎 ИТОГ:
• Multi-stage — must have для прода: меньше размер, выше безопасность.
• Healthchecks — понимай контекст: Dockerfile для standalone, свои probes для K8s.
Сеньор выбирает правильный инструмент для задачи. 👁️🗨️
#Docker #DevOps #SeniorPython
🔥 ТЫ ДУМАЕШЬ, ЧТО ЗНАЕШЬ ТЕСТЫ? А ЧТО НАСЧЁТ ПАРАМЕТРИЗАЦИИ В PYTEST? 🔥
Представь: ты пишешь тест для функции, которая проверяет, является ли число чётным. Ты бы написал 10 отдельных тестов для чисел 2, 4, 6, 8... А если их 100? 1000? Руки отсохнут, код раздуется, а время улетит в трубу. 😱
Вот тут и приходит СУПЕРСИЛА PYTEST — параметризованные тесты! Это как волшебная палочка, которая превращает один скучный тест в мощную машину для проверки сотен сценариев. 🪄
ЧТО ЭТО ТАКОЕ?
Параметризация — это когда ты пишешь ОДИН тест, а pytest запускает его МНОГО РАЗ с разными входными данными и ожидаемыми результатами. Всё гениально и просто!
КАК ЭТО ВЫГЛЯДИТ В КОДЕ?
Вместо того чтобы писать:
Ты пишешь ОДИН раз:
И ВСЁ! 🚀 Один тест, а проверяет 4 случая. Добавил ещё пару кортежей в список — и уже 1000 проверок!
ПОЧЕМУ ЭТО ТАК КРУТО?
• Меньше кода — меньше шансов ошибиться.
• Читаемость — сразу видно, какие кейсы покрыты.
• Расширяемость — добавить новый сценарий = дописать одну строчку.
• Изоляция — каждый запуск — независимый тест. Если один упал, остальные работают.
А ЧТО НАСЧЁТ СЛОЖНЫХ СЛУЧАЕВ?
Можно передавать не только простые значения, но и целые объекты, словари, функции! Хочешь проверить API с разными токенами? Легко:
СОВЕТ ОТ СЕНЬОРА:
Параметризация — это не просто фишка. Это ОБЯЗАТЕЛЬНЫЙ инструмент в арсенале Senior Python разработчика. На собеседовании тебя спросят: "Как ты обеспечиваешь покрытие тестами?" — и твой ответ должен начинаться с "Параметризованные тесты в pytest...".
ЗАПОМНИ:
•
• Один тест — много данных.
• Код становится чище, а ты — увереннее.
Готовься к собесу и помни: сеньор не тот, кто пишет много кода, а тот, кто пишет умный код. 💪
#pytest #параметризация #seniorpython
Представь: ты пишешь тест для функции, которая проверяет, является ли число чётным. Ты бы написал 10 отдельных тестов для чисел 2, 4, 6, 8... А если их 100? 1000? Руки отсохнут, код раздуется, а время улетит в трубу. 😱
Вот тут и приходит СУПЕРСИЛА PYTEST — параметризованные тесты! Это как волшебная палочка, которая превращает один скучный тест в мощную машину для проверки сотен сценариев. 🪄
ЧТО ЭТО ТАКОЕ?
Параметризация — это когда ты пишешь ОДИН тест, а pytest запускает его МНОГО РАЗ с разными входными данными и ожидаемыми результатами. Всё гениально и просто!
КАК ЭТО ВЫГЛЯДИТ В КОДЕ?
Вместо того чтобы писать:
def test_is_even_2():
assert is_even(2) == True
def test_is_even_3():
assert is_even(3) == False
Ты пишешь ОДИН раз:
import pytest
@pytest.mark.parametrize("input, expected", [
(2, True),
(3, False),
(100, True),
(101, False),
])
def test_is_even(input, expected):
assert is_even(input) == expected
И ВСЁ! 🚀 Один тест, а проверяет 4 случая. Добавил ещё пару кортежей в список — и уже 1000 проверок!
ПОЧЕМУ ЭТО ТАК КРУТО?
• Меньше кода — меньше шансов ошибиться.
• Читаемость — сразу видно, какие кейсы покрыты.
• Расширяемость — добавить новый сценарий = дописать одну строчку.
• Изоляция — каждый запуск — независимый тест. Если один упал, остальные работают.
А ЧТО НАСЧЁТ СЛОЖНЫХ СЛУЧАЕВ?
Можно передавать не только простые значения, но и целые объекты, словари, функции! Хочешь проверить API с разными токенами? Легко:
@pytest.mark.parametrize("user_data", [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
])
def test_user_creation(user_data):
result = create_user(user_data)
assert result["name"] == user_data["name"]СОВЕТ ОТ СЕНЬОРА:
Параметризация — это не просто фишка. Это ОБЯЗАТЕЛЬНЫЙ инструмент в арсенале Senior Python разработчика. На собеседовании тебя спросят: "Как ты обеспечиваешь покрытие тестами?" — и твой ответ должен начинаться с "Параметризованные тесты в pytest...".
ЗАПОМНИ:
•
@pytest.mark.parametrize — твой лучший друг.• Один тест — много данных.
• Код становится чище, а ты — увереннее.
Готовься к собесу и помни: сеньор не тот, кто пишет много кода, а тот, кто пишет умный код. 💪
#pytest #параметризация #seniorpython
🔥 Middleware в Django: что это и как написать свой?
Представь, что каждый HTTP-запрос к твоему сайту — это посетитель, который проходит через ряд «пропускных пунктов». Каждый пункт может проверить его, изменить или даже развернуть обратно. Вот это и есть middleware (промежуточное ПО).
Как это работает?
Django обрабатывает запрос по цепочке middleware. Каждый middleware — это класс с методами, которые вызываются на разных этапах:
•
•
•
•
•
•
•
Зачем это нужно?
• Аутентификация и авторизация.
• Логирование запросов.
• Сжатие ответов.
• Блокировка подозрительных IP.
• Добавление заголовков безопасности.
• Обработка CORS.
Как написать кастомный middleware?
Самый простой способ — создать класс с методом
Как подключить?
В файле
Важные нюансы для Senior:
1. Порядок имеет значение — middleware выполняются в том порядке, в котором они указаны в списке. Первый middleware обрабатывает запрос первым, а ответ — последним.
2. Не делай тяжелых операций — каждый middleware выполняется на каждый запрос. Если там будет запрос к базе или внешнему API, производительность упадет.
3. Используй готовые решения — не изобретай велосипед. Django поставляется с набором встроенных middleware (аутентификация, сессии, CSRF, GZip и т.д.).
4. Тестируй — middleware могут влиять на все запросы, поэтому их нужно тщательно тестировать.
5. Не злоупотребляй — чем больше middleware, тем медленнее обработка. Держи цепочку минимальной.
Когда писать свой middleware?
Когда тебе нужно выполнить какое-то действие на каждом запросе или ответе, и это не вписывается в существующие механизмы Django (декораторы, сигналы, контекстные процессоры).
Например:
• Блокировка запросов с определенными User-Agent.
• Добавление кастомных заголовков к ответу.
• Изменение request.user на основе кастомной логики.
Итог:
Middleware — мощный инструмент, который позволяет «вклиниться» в обработку запроса/ответа. Понимание его работы — обязательный навык для Senior Python разработчика. На собеседовании тебя могут попросить написать простой middleware или объяснить, как работает цепочка. Теперь ты готов!
#Django #Middleware #SeniorPython
Представь, что каждый HTTP-запрос к твоему сайту — это посетитель, который проходит через ряд «пропускных пунктов». Каждый пункт может проверить его, изменить или даже развернуть обратно. Вот это и есть middleware (промежуточное ПО).
Как это работает?
Django обрабатывает запрос по цепочке middleware. Каждый middleware — это класс с методами, которые вызываются на разных этапах:
•
__init__ — вызывается один раз при старте сервера.•
__call__ — вызывается на каждый запрос.•
process_request — до того, как Django определит, какой view обработает запрос.•
process_view — после определения view, но до его вызова.•
process_response — после того, как view вернул ответ.•
process_exception — если в view возникло исключение.•
process_template_response — если view вернул шаблонный ответ.Зачем это нужно?
• Аутентификация и авторизация.
• Логирование запросов.
• Сжатие ответов.
• Блокировка подозрительных IP.
• Добавление заголовков безопасности.
• Обработка CORS.
Как написать кастомный middleware?
Самый простой способ — создать класс с методом
__call__. Вот пример, который логирует время выполнения каждого запроса:
import time
class TimingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
start = time.time()
response = self.get_response(request)
end = time.time()
print(f'Request took {end - start:.2f} seconds')
return response
Как подключить?
В файле
settings.py добавь путь к твоему классу в список MIDDLEWARE:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
...
'myapp.middleware.TimingMiddleware',
]
Важные нюансы для Senior:
1. Порядок имеет значение — middleware выполняются в том порядке, в котором они указаны в списке. Первый middleware обрабатывает запрос первым, а ответ — последним.
2. Не делай тяжелых операций — каждый middleware выполняется на каждый запрос. Если там будет запрос к базе или внешнему API, производительность упадет.
3. Используй готовые решения — не изобретай велосипед. Django поставляется с набором встроенных middleware (аутентификация, сессии, CSRF, GZip и т.д.).
4. Тестируй — middleware могут влиять на все запросы, поэтому их нужно тщательно тестировать.
5. Не злоупотребляй — чем больше middleware, тем медленнее обработка. Держи цепочку минимальной.
Когда писать свой middleware?
Когда тебе нужно выполнить какое-то действие на каждом запросе или ответе, и это не вписывается в существующие механизмы Django (декораторы, сигналы, контекстные процессоры).
Например:
• Блокировка запросов с определенными User-Agent.
• Добавление кастомных заголовков к ответу.
• Изменение request.user на основе кастомной логики.
Итог:
Middleware — мощный инструмент, который позволяет «вклиниться» в обработку запроса/ответа. Понимание его работы — обязательный навык для Senior Python разработчика. На собеседовании тебя могут попросить написать простой middleware или объяснить, как работает цепочка. Теперь ты готов!
#Django #Middleware #SeniorPython
ТЫ ДУМАЕШЬ, ЧТО ЗНАЕШЬ SOLID? А СЛАБО ОБЪЯСНИТЬ, ПОЧЕМУ ТВОЙ DJANGO-ПРОЕКТ РАЗВАЛИВАЕТСЯ, КОГДА ТЫ МЕНЯЕШЬ ОДНУ СТРОЧКУ В МОДЕЛИ? 😱
Скорее всего, ты нарушаешь Dependency Inversion Principle (DIP) — принцип инверсии зависимостей. И сегодня мы разберем его так, что на собеседовании ты будешь сыпать терминами и примерами, как сеньор с 10-летним стажем. Поехали!
СУТЬ ПРИНЦИПА ОДНОЙ ФРАЗОЙ
Это правило говорит: НЕ ЗАВИСИ ОТ КОНКРЕТИКИ, ЗАВИСИ ОТ АБСТРАКЦИИ. Твой высокоуровневый код (бизнес-логика) не должен знать, как именно работает низкоуровневый код (база данных, API). Они оба должны общаться через интерфейс (абстракцию).
ПОЧЕМУ ЭТО ВАЖНО?
Представь, что твой сервис отправки писем — это розетка. А конкретная реализация (SMTP, Slack, Telegram) — это вилка. Если ты в коде жёстко прописал «шлём через SMTP», то при смене провайдера тебе придётся переписывать всю бизнес-логику. А если ты воткнул переходник (интерфейс), то просто меняешь вилку — и всё работает. 🔌
КАК ЭТО ВЫГЛЯДИТ В DJANGO?
Самый частый анти-паттерн — когда ты в
А теперь — правильный подход. Мы создаём абстракцию (интерфейс) для работы с заказами:
Теперь твоя бизнес-логика зависит от интерфейса
КАК ПРИМЕНИТЬ ЭТО В РЕАЛЬНОМ DJANGO-ПРОЕКТЕ?
1. Выдели интерфейсы для работы с данными. Не таскай
2. Используй внедрение зависимостей (DI). Передавай зависимости в конструктор или метод, а не создавай их внутри. В Django для этого часто используют
3. Для сложной бизнес-логики — отдельный слой. Не пиши всё во
ЧАСТАЯ ОШИБКА НА СОБЕСЕДОВАНИИ
Многие путают DIP с Dependency Injection (DI). Запомни: DIP — это принцип (ЧТО делать), а DI — это паттерн (КАК делать). DIP говорит «зависи от абстракций», а DI предлагает способ это реализовать — передавать зависимости извне.
ПОЧЕМУ ЭТО СПАСЁТ ТВОЙ ПРОЕКТ?
• Тестируемость. Ты можешь подменить реальный репозиторий на фейковый (mock) в тестах, не трогая базу данных.
• Гибкость. Смена технологий становится простой заменой одной реализации на другую.
• Читаемость. Код становится чище, потому что бизнес-логика не засорена деталями работы с БД.
ИТОГ
DIP — это не просто абстрактная теория из книжек. Это реальный инструмент, который делает твой код на Django гибким, тестируемым и готовым к изменениям. Начни с малого — вынеси работу с моделями в репозитории, и ты почувствуешь разницу.
А теперь вопрос к тебе: сколько мест в твоём проекте напрямую обращаются к
#Python #Django #SOLID #DIP #Собеседование #SeniorPython
Скорее всего, ты нарушаешь Dependency Inversion Principle (DIP) — принцип инверсии зависимостей. И сегодня мы разберем его так, что на собеседовании ты будешь сыпать терминами и примерами, как сеньор с 10-летним стажем. Поехали!
СУТЬ ПРИНЦИПА ОДНОЙ ФРАЗОЙ
Это правило говорит: НЕ ЗАВИСИ ОТ КОНКРЕТИКИ, ЗАВИСИ ОТ АБСТРАКЦИИ. Твой высокоуровневый код (бизнес-логика) не должен знать, как именно работает низкоуровневый код (база данных, API). Они оба должны общаться через интерфейс (абстракцию).
ПОЧЕМУ ЭТО ВАЖНО?
Представь, что твой сервис отправки писем — это розетка. А конкретная реализация (SMTP, Slack, Telegram) — это вилка. Если ты в коде жёстко прописал «шлём через SMTP», то при смене провайдера тебе придётся переписывать всю бизнес-логику. А если ты воткнул переходник (интерфейс), то просто меняешь вилку — и всё работает. 🔌
КАК ЭТО ВЫГЛЯДИТ В DJANGO?
Самый частый анти-паттерн — когда ты в
views.py или services.py напрямую дёргаешь модель и её методы. Вот так делать НЕЛЬЗЯ:
# ❌ ПЛОХО: жёсткая зависимость от модели
from .models import Order
def send_invoice(order_id):
order = Order.objects.get(id=order_id)
# ... логика, которая знает про поля модели
А теперь — правильный подход. Мы создаём абстракцию (интерфейс) для работы с заказами:
# ✅ ХОРОШО: зависим от абстракции
from abc import ABC, abstractmethod
class OrderRepository(ABC):
@abstractmethod
def get_by_id(self, order_id):
pass
class DjangoOrderRepository(OrderRepository):
def get_by_id(self, order_id):
from .models import Order
return Order.objects.get(id=order_id)
Теперь твоя бизнес-логика зависит от интерфейса
OrderRepository, а не от конкретной модели. И если завтра ты перейдёшь с PostgreSQL на MongoDB или вообще на внешний API — ты просто создашь новую реализацию интерфейса, и всё продолжит работать! 🚀КАК ПРИМЕНИТЬ ЭТО В РЕАЛЬНОМ DJANGO-ПРОЕКТЕ?
1. Выдели интерфейсы для работы с данными. Не таскай
Model.objects.filter() по всему проекту. Создай репозитории или сервисы.2. Используй внедрение зависимостей (DI). Передавай зависимости в конструктор или метод, а не создавай их внутри. В Django для этого часто используют
django-injector или просто передают зависимости через аргументы функций.3. Для сложной бизнес-логики — отдельный слой. Не пиши всё во
views.py. Вынеси логику в services.py, который будет зависеть от абстракций.ЧАСТАЯ ОШИБКА НА СОБЕСЕДОВАНИИ
Многие путают DIP с Dependency Injection (DI). Запомни: DIP — это принцип (ЧТО делать), а DI — это паттерн (КАК делать). DIP говорит «зависи от абстракций», а DI предлагает способ это реализовать — передавать зависимости извне.
ПОЧЕМУ ЭТО СПАСЁТ ТВОЙ ПРОЕКТ?
• Тестируемость. Ты можешь подменить реальный репозиторий на фейковый (mock) в тестах, не трогая базу данных.
• Гибкость. Смена технологий становится простой заменой одной реализации на другую.
• Читаемость. Код становится чище, потому что бизнес-логика не засорена деталями работы с БД.
ИТОГ
DIP — это не просто абстрактная теория из книжек. Это реальный инструмент, который делает твой код на Django гибким, тестируемым и готовым к изменениям. Начни с малого — вынеси работу с моделями в репозитории, и ты почувствуешь разницу.
А теперь вопрос к тебе: сколько мест в твоём проекте напрямую обращаются к
Model.objects? Если больше десяти — пора рефакторить! 🔥#Python #Django #SOLID #DIP #Собеседование #SeniorPython