🔒 Декораторы для улучшения безопасности API
📌 Этот декоратор добавляет проверку аутентификации для функции, что полезно для защиты API от неавторизованного доступа. Он оборачивает функцию, проверяет наличие флага аутентификации и выбрасывает исключение, если доступ запрещен. Это может быть полезно, например, в веб-приложениях, где безопасность имеет первостепенное значение.
Подпишись 👉🏻 @KodduuPython 🤖
from functools import wraps
def require_authentication(func):
@wraps(func)
def wrapper(*args, **kwargs):
user_authenticated = kwargs.get('authenticated', False)
if not user_authenticated:
raise PermissionError("Требуется аутентификация для доступа к этой функции.")
return func(*args, **kwargs)
return wrapper
# Пример использования
@require_authentication
def get_user_data(user_id: int, authenticated=False) -> dict:
# Имитация получения данных пользователя
return {"user_id": user_id, "name": "Alice"}
try:
print(get_user_data(user_id=1, authenticated=True)) # Успешный доступ
print(get_user_data(user_id=2, authenticated=False)) # Ошибка доступа
except PermissionError as e:
print(e)
📌 Этот декоратор добавляет проверку аутентификации для функции, что полезно для защиты API от неавторизованного доступа. Он оборачивает функцию, проверяет наличие флага аутентификации и выбрасывает исключение, если доступ запрещен. Это может быть полезно, например, в веб-приложениях, где безопасность имеет первостепенное значение.
Подпишись 👉🏻 @KodduuPython 🤖
⚡️ Реактивное программирование с RxPy
📌 Этот код демонстрирует использование RxPy для асинхронного веб-скрапинга. Он создает поток URL-адресов, которые обрабатываются параллельно с помощью многопоточного планировщика. Каждый URL запрашивается, и результат выводится в консоль. Такой подход полезен для обработки большого количества запросов или выполнения асинхронных задач.
Подпишись 👉🏻 @KodduuPython 🤖
import rx
from rx import operators as ops
from rx.scheduler import ThreadPoolScheduler
import requests
def fetch_url(url: str) -> str:
try:
response = requests.get(url)
response.raise_for_status()
return f"Fetched {url} with status {response.status_code}"
except requests.RequestException as e:
return f"Error fetching {url}: {str(e)}"
urls = [
"http://example.com",
"http://nonexistent.url",
"http://example.org"
]
# Настройка многопоточного планировщика
scheduler = ThreadPoolScheduler(max_workers=2)
# Создание реактивного потока
rx.from_(urls).pipe(
ops.map(lambda url: fetch_url(url)),
ops.do_action(lambda result: print(result))
).subscribe(
on_error=lambda e: print(f"Error occurred: {e}"),
on_completed=lambda: print("Fetching completed!")
)
📌 Этот код демонстрирует использование RxPy для асинхронного веб-скрапинга. Он создает поток URL-адресов, которые обрабатываются параллельно с помощью многопоточного планировщика. Каждый URL запрашивается, и результат выводится в консоль. Такой подход полезен для обработки большого количества запросов или выполнения асинхронных задач.
Подпишись 👉🏻 @KodduuPython 🤖
🚀 Улучшение производительности веб-приложений с помощью Asyncio
📌 Этот код демонстрирует, как использовать асинхронные операции для выполнения нескольких HTTP-запросов параллельно. С помощью библиотек
Подпишись 👉🏻 @KodduuPython 🤖
import asyncio
import aiohttp
async def fetch_data(url: str) -> dict:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
try:
return await response.json()
except aiohttp.ContentTypeError:
print("Получен ответ, не являющийся JSON")
else:
response.raise_for_status()
async def main():
urls = [
'https://api.example.com/data1',
'https://api.example.com/data2',
'https://api.example.com/data3',
]
tasks = [fetch_data(url) for url in urls]
results = await asyncio.gather(*tasks)
for result in results:
print(result)
# Запуск асинхронной программы
asyncio.run(main())
📌 Этот код демонстрирует, как использовать асинхронные операции для выполнения нескольких HTTP-запросов параллельно. С помощью библиотек
aiohttp и asyncio можно значительно сократить время отклика при работе с сетевыми запросами, так как они выполняются без блокировки основного потока. Такая техника особенно полезна для веб-приложений, которые часто обращаются к внешним API.Подпишись 👉🏻 @KodduuPython 🤖
👍2
🗄️ Оптимизация запросов к базам данных с использованием SQLAlchemy
📌 Этот код демонстрирует использование SQLAlchemy для оптимизации запросов к базе данных с помощью
Подпишись 👉🏻 @KodduuPython 🤖
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, joinedload
Base = declarative_base()
class Author(Base):
__tablename__ = 'authors'
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
class Book(Base):
__tablename__ = 'books'
id = Column(Integer, primary_key=True)
title = Column(String, nullable=False)
author_id = Column(Integer, ForeignKey('authors.id'))
author = relationship('Author', back_populates='books')
Author.books = relationship('Book', order_by=Book.id, back_populates='author')
# Настройка базы данных
engine = create_engine('sqlite:///:memory:')
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
# Пример использования: Избегание избыточных запросов с помощью joinedload
def get_books_with_authors():
with Session() as session:
try:
books = session.query(Book).options(joinedload(Book.author)).all()
return [(book.title, book.author.name) for book in books]
except Exception as e:
print(f"Ошибка: {e}")
# Создание примеров данных
with Session() as session:
author = Author(name='J.K. Rowling')
book = Book(title='Harry Potter', author=author)
session.add(author)
session.add(book)
session.commit()
# Вызов функции
print(get_books_with_authors())
📌 Этот код демонстрирует использование SQLAlchemy для оптимизации запросов к базе данных с помощью
joinedload. Эта техника уменьшает количество SQL-запросов за счет загрузки связанных данных в одно обращение, что особенно полезно при работе с большими объемами данных.Подпишись 👉🏻 @KodduuPython 🤖
👍2
🌱 Симуляция клеточного автомата "Жизнь"
📌 Этот код демонстрирует реализацию клеточного автомата "Жизнь" Джона Конвея. Алгоритм моделирует эволюцию клеток на двумерной сетке с простыми правилами: клетка остаётся живой, если у неё 2 или 3 живых соседа; иначе умирает. Новый организм рождается, если у пустой клетки ровно 3 живых соседа. Попробуйте изменить размер сетки или вероятность начального состояния, чтобы увидеть разные паттерны.
Подпишись 👉🏻 @KodduuPython 🤖
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
def update(frame_num, img, grid, N):
new_grid = grid.copy()
for i in range(N):
for j in range(N):
# Считаем количество живых соседей
total = (grid[i, (j-1)%N] + grid[i, (j+1)%N] +
grid[(i-1)%N, j] + grid[(i+1)%N, j] +
grid[(i-1)%N, (j-1)%N] + grid[(i-1)%N, (j+1)%N] +
grid[(i+1)%N, (j-1)%N] + grid[(i+1)%N, (j+1)%N])
# Правила игры
if grid[i, j] == 1:
if total < 2 or total > 3:
new_grid[i, j] = 0
elif total == 3:
new_grid[i, j] = 1
img.set_data(new_grid)
grid[:] = new_grid[:]
return img,
def main():
N = 100 # Размер сетки
# Создаем начальную конфигурацию клеток
grid = np.random.choice([0, 1], N*N, p=[0.8, 0.2]).reshape(N, N)
fig, ax = plt.subplots()
img = ax.imshow(grid, interpolation='nearest')
ani = animation.FuncAnimation(fig, update, fargs=(img, grid, N),
frames=200, interval=300, save_count=50)
plt.show()
if __name__ == '__main__':
main()
📌 Этот код демонстрирует реализацию клеточного автомата "Жизнь" Джона Конвея. Алгоритм моделирует эволюцию клеток на двумерной сетке с простыми правилами: клетка остаётся живой, если у неё 2 или 3 живых соседа; иначе умирает. Новый организм рождается, если у пустой клетки ровно 3 живых соседа. Попробуйте изменить размер сетки или вероятность начального состояния, чтобы увидеть разные паттерны.
Подпишись 👉🏻 @KodduuPython 🤖
🤖 Создание Telegram чат-бота для автоматизации задач
📌 Этот код создает Telegram чат-бота, который может устанавливать напоминания. Бот принимает команды от пользователя и позволяет задавать время для напоминания в секундах. Подходит для автоматизации задач, таких как планирование встреч или отправка напоминаний.
🛠 pip install python-telegram-bot
Подпишись 👉🏻 @KodduuPython 🤖
import logging
from telegram import Update
from telegram.ext import Updater, CommandHandler, CallbackContext
logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)
def start(update: Update, context: CallbackContext) -> None:
update.message.reply_text('Привет! Я ваш помощник для автоматизации задач.')
def remind(context: CallbackContext) -> None:
chat_id = context.job.context
context.bot.send_message(chat_id=chat_id, text='Время для вашего напоминания!')
def schedule_reminder(update: Update, context: CallbackContext) -> None:
try:
delay = int(context.args[0])
chat_id = update.message.chat_id
update.message.reply_text(f'Напоминание установлено на {delay} секунд!')
context.job_queue.run_once(remind, delay, context=chat_id)
except (IndexError, ValueError):
update.message.reply_text('Используйте: /remind <время в секундах>')
def main():
updater = Updater("YOUR_TELEGRAM_BOT_TOKEN", use_context=True)
dispatcher = updater.dispatcher
dispatcher.add_handler(CommandHandler("start", start))
dispatcher.add_handler(CommandHandler("remind", schedule_reminder))
updater.start_polling()
updater.idle()
if __name__ == '__main__':
main()
📌 Этот код создает Telegram чат-бота, который может устанавливать напоминания. Бот принимает команды от пользователя и позволяет задавать время для напоминания в секундах. Подходит для автоматизации задач, таких как планирование встреч или отправка напоминаний.
🛠 pip install python-telegram-bot
Подпишись 👉🏻 @KodduuPython 🤖
🔍 Анализ тональности текстов с помощью NLTK и машинного обучения
📌 Этот код использует NLTK для обработки текстов и Naive Bayes для анализа настроения. Это полезно для автоматической оценки отзывов и комментариев, что может помочь в бизнесе для понимания клиентской лояльности.
Подпишись 👉🏻 @KodduuPython 🤖
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
nltk.download('punkt')
nltk.download('stopwords')
# Пример данных
texts = ["I love this product!", "This is the worst experience ever.", "Amazing quality, will buy again!", "Not worth the price."]
labels = [1, 0, 1, 0] # 1 - положительный, 0 - отрицательный
# Предварительная обработка текстов
def preprocess_text(text):
tokens = word_tokenize(text.lower())
tokens = [word for word in tokens if word.isalpha()]
return [word for word in tokens if word not in stopwords.words('english')]
processed_texts = [" ".join(preprocess_text(text)) for text in texts]
# Векторизация текстов и обучение модели
vectorizer = CountVectorizer()
X = vectorizer.fit_transform(processed_texts)
X_train, X_test, y_train, y_test = train_test_split(X, labels, test_size=0.25, random_state=42)
model = MultinomialNB()
model.fit(X_train, y_train)
# Тестирование модели
predictions = model.predict(X_test)
print(f"Точность: {accuracy_score(y_test, predictions)}")
# Применение к новому тексту
new_text = "I am very happy with this purchase!"
processed_new_text = vectorizer.transform([" ".join(preprocess_text(new_text))])
print(f"Тональность: {'Положительная' if model.predict(processed_new_text)[0] == 1 else 'Отрицательная'}")
📌 Этот код использует NLTK для обработки текстов и Naive Bayes для анализа настроения. Это полезно для автоматической оценки отзывов и комментариев, что может помочь в бизнесе для понимания клиентской лояльности.
Подпишись 👉🏻 @KodduuPython 🤖
📊 Анализ настроений с NLTK
📌 Этот код использует библиотеку Natural Language Toolkit (NLTK) для анализа настроений в текстах. С помощью SentimentIntensityAnalyzer и лексикона VADER, он оценивает полярность текста, классифицируя его как позитивный, негативный или нейтральный. Это полезно для анализа отзывов клиентов или комментариев в социальных сетях.
Перед использованием кода установите NLTK:
Подпишись 👉🏻 @KodduuPython 🤖
import nltk
from nltk.sentiment import SentimentIntensityAnalyzer
# Убедитесь, что необходимые ресурсы загружены
nltk.download('vader_lexicon')
def analyze_sentiment(text: str) -> str:
sia = SentimentIntensityAnalyzer()
sentiment_scores = sia.polarity_scores(text)
compound_score = sentiment_scores['compound']
if compound_score >= 0.05:
return 'Positive'
elif compound_score <= -0.05:
return 'Negative'
else:
return 'Neutral'
# Пример использования
text = "I absolutely love this new phone!"
print(f"The sentiment of the text is: {analyze_sentiment(text)}")
📌 Этот код использует библиотеку Natural Language Toolkit (NLTK) для анализа настроений в текстах. С помощью SentimentIntensityAnalyzer и лексикона VADER, он оценивает полярность текста, классифицируя его как позитивный, негативный или нейтральный. Это полезно для анализа отзывов клиентов или комментариев в социальных сетях.
Перед использованием кода установите NLTK:
pip install nltk и загрузите ресурсы: nltk.download('vader_lexicon').Подпишись 👉🏻 @KodduuPython 🤖
Forwarded from AIGENTTO
Проблемы внедрения AI в компании
Уже давно есть все инструменты - ИИ, ИИ агенты, мультиагентные системы, и наконец паттерн ReAct (OpenClaw). Последний реально может довольно быстро автоматизировать почти любые процессы.
Но реальное внедрение буксует, вот некоторые причины:
👉 Саботаж и отказ сотрудников что-то менять (автокассы в магазинах тоже прошли этот путь), ведь могут по сути автоматизировать и уволить сотрудников.
👉 Нехватка IT-опыта (когда этим занимаются не IT-специалисты, а вайбкодеры)
👉 Отказ IT-специалистов что-то менять (удивительно, но я сталкиваюсь с жутким консерватизмом со стороны самих IT-специалистов)
👉 Боязнь потратить много токенов (жадность?)
Но что показал эксперимент с roll-up компаниями типа Dwelly, оказывается, даже в небольших бизнесах, которые купил новый собственник, можно все перевести на рельсы AI OS под конкретную вертикаль, и прибыльность бизнеса вырастает с 10% до 40% в год (это в Великобритании).
Вывод прост - только владелец может ИИзировать свою компанию, только тот, кто имеет абсолютный интерес и абсолютную власть в своей компании. К сожалению, даже топ-менеджеры здесь не подходят, потому что им выгодно много людей и отсутствие изменений, так они ничем не рискуют.
Либо собственник должен нанять ИТ-драйвера, которому будет выделена доля в компании в случае успеха, и дать ему абсолютную власть, иначе опять не работает. Все остальное - полумеры, пилоты, которые, конечно, дают иногда результат, но чаще нет, чем да.
Еще раз - суть в том, чтобы был человек, владеющий долей в компании и имеющий абсолютную власть. Опыт roll-ups показывает, что иногда сопротивляются даже собственники, а вот когда у тебя купили компанию, то все сопротивление заканчивается.
Если вам интересна тема, поставьте 👂, я напишу про реальные кейсы провалов и успехов.
Подпишись 👉🏻 @aigentto 🤖
Уже давно есть все инструменты - ИИ, ИИ агенты, мультиагентные системы, и наконец паттерн ReAct (OpenClaw). Последний реально может довольно быстро автоматизировать почти любые процессы.
Но реальное внедрение буксует, вот некоторые причины:
👉 Саботаж и отказ сотрудников что-то менять (автокассы в магазинах тоже прошли этот путь), ведь могут по сути автоматизировать и уволить сотрудников.
👉 Нехватка IT-опыта (когда этим занимаются не IT-специалисты, а вайбкодеры)
👉 Отказ IT-специалистов что-то менять (удивительно, но я сталкиваюсь с жутким консерватизмом со стороны самих IT-специалистов)
👉 Боязнь потратить много токенов (жадность?)
Но что показал эксперимент с roll-up компаниями типа Dwelly, оказывается, даже в небольших бизнесах, которые купил новый собственник, можно все перевести на рельсы AI OS под конкретную вертикаль, и прибыльность бизнеса вырастает с 10% до 40% в год (это в Великобритании).
Вывод прост - только владелец может ИИзировать свою компанию, только тот, кто имеет абсолютный интерес и абсолютную власть в своей компании. К сожалению, даже топ-менеджеры здесь не подходят, потому что им выгодно много людей и отсутствие изменений, так они ничем не рискуют.
Либо собственник должен нанять ИТ-драйвера, которому будет выделена доля в компании в случае успеха, и дать ему абсолютную власть, иначе опять не работает. Все остальное - полумеры, пилоты, которые, конечно, дают иногда результат, но чаще нет, чем да.
Еще раз - суть в том, чтобы был человек, владеющий долей в компании и имеющий абсолютную власть. Опыт roll-ups показывает, что иногда сопротивляются даже собственники, а вот когда у тебя купили компанию, то все сопротивление заканчивается.
Если вам интересна тема, поставьте 👂, я напишу про реальные кейсы провалов и успехов.
Подпишись 👉🏻 @aigentto 🤖
🔄 Асинхронная работа с API в функциональном стиле
📌 Этот код демонстрирует, как использовать асинхронное программирование для выполнения параллельных запросов к API. Мы применяем
Подпишись 👉🏻 @KodduuPython 🤖
import asyncio
import aiohttp
from typing import List
# Функция для выполнения запроса к API
async def fetch_data(session: aiohttp.ClientSession, url: str) -> dict:
async with session.get(url) as response:
response.raise_for_status() # Проверка на ошибки HTTP
return await response.json() # Возврат JSON-ответа
# Функция для выполнения запросов ко всем URL-адресам
async def fetch_all_data(urls: List[str]) -> List[dict]:
async with aiohttp.ClientSession() as session:
tasks = [fetch_data(session, url) for url in urls] # Создание задач для всех URL
return await asyncio.gather(*tasks, return_exceptions=True) # Сбор результатов
# Пример использования
async def main():
urls = [
"https://jsonplaceholder.typicode.com/posts/1",
"https://jsonplaceholder.typicode.com/posts/2",
"https://jsonplaceholder.typicode.com/posts/3",
]
results = await fetch_all_data(urls)
for result in results:
print(result)
# Запуск асинхронного кода
asyncio.run(main())
📌 Этот код демонстрирует, как использовать асинхронное программирование для выполнения параллельных запросов к API. Мы применяем
asyncio и aiohttp для асинхронной загрузки данных с нескольких URL-адресов. Такой подход улучшает производительность при взаимодействии с внешними API, что актуально для веб-приложений и сервисов, работающих с большими объемами данных. Подпишись 👉🏻 @KodduuPython 🤖
🚀 Лайфхак: @lru_cache ускоряет рекурсию в тысячи раз!
📌 Декоратор @lru_cache автоматически кэширует результаты вызовов функции. Повторные вычисления с теми же аргументами мгновенно берутся из памяти — никаких лишних рекурсий. Идеально для динамического программирования, алгоритмов на графах, парсинга и любых функций с повторяющимися подзадачами.
Подпишись 👉🏻 @KodduuPython 🤖
import time
from functools import lru_cache
@lru_cache(maxsize=None) # Неограниченный кэш — храним ВСЕ уникальные результаты
def fibonacci(n: int) -> int:
"""Рекурсивное вычисление n-го числа Фибоначчи."""
if n < 2:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
if __name__ == "__main__":
try:
n = 40 # Без кэша это заняло бы минуты или часы!
start = time.time()
result = fibonacci(n)
duration = time.time() - start
print(f"Фибоначчи({n}) = {result}")
print(f"Время с мемоизацией: {duration:.6f} сек")
except Exception as e:
print(f"Ошибка: {e}")
📌 Декоратор @lru_cache автоматически кэширует результаты вызовов функции. Повторные вычисления с теми же аргументами мгновенно берутся из памяти — никаких лишних рекурсий. Идеально для динамического программирования, алгоритмов на графах, парсинга и любых функций с повторяющимися подзадачами.
Подпишись 👉🏻 @KodduuPython 🤖
✨ singledispatch: Полиморфизм по типу без if и классов!
📌 Декоратор @singledispatch превращает одну функцию в набор реализаций по типу первого аргумента. Никаких if isinstance — просто регистрируй обработчики. Идеально для парсеров данных, сериализаторов, валидаторов и API, где нужно красиво обрабатывать int, str, list, dict и свои классы.
Подпишись 👉🏻 @KodduuPython 🤖
from functools import singledispatch
from typing import Any
@singledispatch
def format_value(value: Any) -> str:
"""Обработка по умолчанию для неизвестных типов."""
return f"Неизвестный тип ({type(value).__name__}): {value}"
@format_value.register
def _(value: int) -> str:
return f"Целое число: {value} (в hex: {value:x})"
@format_value.register
def _(value: float) -> str:
return f"Число с плавающей точкой: {value:.4f}"
@format_value.register
def _(value: str) -> str:
return f"Строка длиной {len(value)}: \"{value[:50]}{'...' if len(value) > 50 else ''}\""
@format_value.register(list)
@format_value.register(tuple)
def _(value) -> str:
formatted = [format_value(item) for item in value[:3]]
return f"Коллекция ({len(value)} элементов): [{', '.join(formatted)}]"
if __name__ == "__main__":
try:
tests = [42, 3.14159, "Привет из Python!", [1, 2, "текст", 4.5]]
for test in tests:
print(format_value(test))
except Exception as e:
print(f"Ошибка: {e}")
📌 Декоратор @singledispatch превращает одну функцию в набор реализаций по типу первого аргумента. Никаких if isinstance — просто регистрируй обработчики. Идеально для парсеров данных, сериализаторов, валидаторов и API, где нужно красиво обрабатывать int, str, list, dict и свои классы.
Подпишись 👉🏻 @KodduuPython 🤖
🔥 @cached_property: Дорогие свойства вычисляются только один раз!
📌 @cached_property превращает метод в свойство, которое вычисляется только при первом обращении и потом кэшируется в экземпляре класса. Идеально для аналитики, обработки данных, машинного обучения и любых классов, где есть «тяжелые» свойства.
Подпишись 👉🏻 @KodduuPython 🤖
from functools import cached_property
import time
from typing import List
class DataAnalyzer:
def __init__(self, dataset: List[float]):
self.dataset = dataset
@cached_property
def mean(self) -> float:
"""Вычисляет среднее значение (имитация тяжелой операции)."""
print("🔄 Вычисляем среднее...")
time.sleep(1.2) # Имитация долгого расчёта
return sum(self.dataset) / len(self.dataset)
@cached_property
def std_dev(self) -> float:
"""Вычисляет стандартное отклонение."""
print("🔄 Вычисляем стандартное отклонение...")
time.sleep(0.9)
mean_val = self.mean
variance = sum((x - mean_val) ** 2 for x in self.dataset) / len(self.dataset)
return variance ** 0.5
if __name__ == "__main__":
try:
data = [2.5, 3.7, 6.8, 9.1, 4.3, 7.6]
analyzer = DataAnalyzer(data)
start = time.time()
print(f"Среднее: {analyzer.mean:.2f}")
print(f"Стандартное отклонение: {analyzer.std_dev:.2f}")
# Повторные обращения — мгновенно
print(f"Среднее (повтор): {analyzer.mean:.2f}")
print(f"Общее время: {time.time() - start:.2f} секунд")
except Exception as e:
print(f"Ошибка: {e}")
📌 @cached_property превращает метод в свойство, которое вычисляется только при первом обращении и потом кэшируется в экземпляре класса. Идеально для аналитики, обработки данных, машинного обучения и любых классов, где есть «тяжелые» свойства.
Подпишись 👉🏻 @KodduuPython 🤖
🔥 Retry-декоратор: спасение от нестабильных API и сетевых сбоев
📌 Этот декоратор автоматически повторяет функцию при указанных ошибках с увеличивающейся задержкой. Exponential backoff + возможность указывать исключения — must-have для работы с API, базами данных, парсерами и любыми внешними сервисами.
Подпишись 👉🏻 @KodduuPython 🤖
import time
import random
from functools import wraps
from typing import Callable, Any
def retry(max_attempts: int = 5,
initial_delay: float = 1.0,
backoff: float = 2.0,
exceptions: tuple = (Exception,)):
"""Декоратор для автоматического повторения функции при ошибках."""
def decorator(func: Callable) -> Callable:
@wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> Any:
delay = initial_delay
last_exception = None
for attempt in range(1, max_attempts + 1):
try:
return func(*args, **kwargs)
except exceptions as e:
last_exception = e
if attempt == max_attempts:
break
print(f"⚠️ Попытка {attempt}/{max_attempts} не удалась: {e}")
print(f"⏳ Ждём {delay:.1f} сек...")
time.sleep(delay)
delay *= backoff # экспоненциальный backoff
raise last_exception
return wrapper
return decorator
# Пример использования
@retry(max_attempts=4, initial_delay=0.5, exceptions=(ValueError, ConnectionError))
def unreliable_api_call():
"""Имитируем нестабильный внешний сервис."""
if random.random() < 0.7: # 70% шанс ошибки
raise ConnectionError("Сервер временно недоступен")
return "Успешный ответ от API!"
if __name__ == "__main__":
try:
result = unreliable_api_call()
print(f"✅ Результат: {result}")
except Exception as e:
print(f"❌ Все попытки исчерпаны. Последняя ошибка: {e}")
📌 Этот декоратор автоматически повторяет функцию при указанных ошибках с увеличивающейся задержкой. Exponential backoff + возможность указывать исключения — must-have для работы с API, базами данных, парсерами и любыми внешними сервисами.
Подпишись 👉🏻 @KodduuPython 🤖
🆒2
🔥 Pydantic v2: Самая мощная валидация данных в Python
📌 Pydantic автоматически проверяет типы, формат email, диапазоны значений, конвертирует строки в datetime и выдаёт понятные ошибки. Must-have для REST API, конфигов, форм, парсинга JSON и любой работы с внешними данными.
🛠 pip install pydantic
Подпишись 👉🏻 @KodduuPython 🤖
from pydantic import BaseModel, Field, ValidationError, EmailStr
from typing import List
from datetime import datetime
class User(BaseModel):
"""Модель пользователя с автоматической валидацией полей."""
id: int
username: str = Field(min_length=4, max_length=20)
email: EmailStr
age: int = Field(ge=16, le=99)
is_active: bool = True
skills: List[str] = Field(default_factory=list)
if __name__ == "__main__":
try:
data = {
"id": 101,
"username": "devpython",
"email": "hello@kodduu.ru",
"age": 27,
"skills": ["Python", "FastAPI", "Pydantic"]
}
user = User.model_validate(data)
print(f"✅ Пользователь валиден: {user.username}")
print(f"Email: {user.email}")
print(f"Навыки: {user.skills}")
# Пример ошибки валидации
bad_data = data.copy()
bad_data["email"] = "неправильный email"
bad_data["age"] = 10
User.model_validate(bad_data)
except ValidationError as e:
print("❌ Ошибка валидации:")
for error in e.errors(include_url=False):
print(f" • {' -> '.join(map(str, error['loc']))}: {error['msg']}")
except Exception as e:
print(f"Ошибка: {e}")
📌 Pydantic автоматически проверяет типы, формат email, диапазоны значений, конвертирует строки в datetime и выдаёт понятные ошибки. Must-have для REST API, конфигов, форм, парсинга JSON и любой работы с внешними данными.
🛠 pip install pydantic
Подпишись 👉🏻 @KodduuPython 🤖
🔥 Loguru: Логирование, которое реально удобно использовать
📌 Loguru заменяет стандартный logging одной строкой настройки. Красивые цвета, автоматическая запись в файл, ротация логов, перехват всех исключений через @logger.catch — и никаких boilerplate-кодов. Идеально для скриптов, CLI, веб-сервисов и продакшена.
🛠 pip install loguru
Подпишись 👉🏻 @KodduuPython 🤖
from loguru import logger
import sys
# Удаляем стандартные обработчики, чтобы не было дублей
logger.remove()
# Вывод в консоль с цветами и красивым форматом
logger.add(
sys.stdout,
format="<green>{time:HH:mm:ss}</green> | <level>{level:8}</level> | {message}",
level="DEBUG",
colorize=True
)
# Запись в файл с автоматической ротацией
logger.add(
"logs/app_{time:YYYY-MM-DD}.log",
rotation="10 MB",
retention="7 days",
level="INFO"
)
@logger.catch
def risky_operation(x: int) -> float:
"""Пример опасной операции с автоматическим логированием исключений."""
return 100 / x
if __name__ == "__main__":
try:
logger.info("🚀 Приложение успешно запущено")
logger.debug("Это отладочное сообщение для разработчика")
result = risky_operation(25)
logger.success(f"✅ Результат расчёта: {result}")
# Вызовем ошибку специально
risky_operation(0)
except Exception as e:
logger.error(f"❌ Неожиданная ошибка: {e}")
📌 Loguru заменяет стандартный logging одной строкой настройки. Красивые цвета, автоматическая запись в файл, ротация логов, перехват всех исключений через @logger.catch — и никаких boilerplate-кодов. Идеально для скриптов, CLI, веб-сервисов и продакшена.
🛠 pip install loguru
Подпишись 👉🏻 @KodduuPython 🤖
👏1
Forwarded from AIGENTTO
Проблема автоматизации чего-либо — это не технология
Начну издалека: автоматизация чего-либо — это не новшество: 100+ лет назад человек переходил от лошади к трактору, примерно в то же время — от ручного труда к ткацкому станку и т. д.
Каждый раз производительность росла, и ВВП на душу населения рос, что приводило к увеличению благ на каждого человека. Поэтому страх, что всех уволят, сильно преувеличен, а точнее, это может стать правдой в моменте, но в долгую AI увеличит блага на душу населения, и так или иначе они все равно будут распределены между людьми.
Теперь переместимся чуть ближе в 2014 год: я нанят в "Большой зеленый банк" как Head автоматизации всего QA, то есть автоматизировать все тестирования всех систем компании (200+ очень разношерстных приложений). Тогда еще не было современного AI, хотя эксперимент мы проводили по автоматизации через распознавание экрана с помощью библиотек Google, все на самом деле даже работало, но со скроллами и legacy интерфейсами были проблемы 🤷♂️
Короче, взяли на тот момент уже стандарт BDD+Java+Selenium driver для всего зоопарка Web+Rest API и уникальные всякие штуки для других областей — была там и знаменитая роборука, которая физически тестировала карточки, вставляя их в терминал 🙂
В тот момент проблемой была не технология, хотя с ней были отдельные решаемые сложности. То же самое сейчас - AI не является блокером, в том же паттерне ReAct (читай OpenClaw) может делать 95% дел которые люди делают за компом.
Тогда главной проблемой были люди, а точнее, их интересы: 5 топ-менеджеров компании управляли большими секторами тестирования и с удовольствием выбивали себе огромные бюджеты на найм ручных тестировщиков. Я, по сути, был призван остановить этот бесконечный найм в ручное тестирование и, по факту, стал главным врагом как минимум этих топ-5 менеджеров, а как максимум — всех 2000+ ручных тестировщиков, которые хотели получать зарплату, тыкать кнопки и не очень хотели учить Java и переходить на автоматизацию.
Для понимания накала страстей, в один момент один из этих топ-5 менеджеров то ли в шутку, то ли всерьёз начал на меня кидаться, так сильно я ему мешал 🙂
Я бы хотел сказать, что победили автоматизация и здравый смысл, но так не работает на больших системах, тем не менее через 4 года уровень автоматизации QA вырос с 0 до 30+%, с учетом того, что за это время внедрили еще 10-ки новых приложений и сам объем тестирования вырос в разы. То есть цель автоматизации в 100% была убегающей: вчера 100% — это было 100 000 тестов, завтра — это 200 000 тестов и так далее.
Почему всё-таки получилось сдержать рост ручного труда и, по факту, сэкономить до 300 млн руб. в год на ручном тестировании? Причина была не в том, что я гений автоматизации, причина была не в технологии. Причина была только в том, что мне дали полный ownership, и директор департамента требовал с меня результат, но не лез в то, как и с помощью чего я буду это делать: вначале там была технология и команда из XIX века, я её убрал за один день, несмотря на большую любовь многих к этой технологии и команде, а любовь была потому, что ребята были приятные и никого сильно не напрягали.
И главное — директор департамента дал мне право на внедрение изменений и всегда его поддерживал. Да, конечно, я не шел напролом, я договаривался с теми 5 топ-менеджерами, но у меня было абсолютное право финального решения по всем вопросам автоматизации.
Только полный ownership и право принимать финальные решения по вопросам в моей зоне ответственности позволили добиться большого результата.
Следующими постами я расскажу, как проваливают текущую AI-автоматизацию большие и малые компании. Нельзя просто дать денег и не дать ownership. Нельзя просто нанять ИТшников, чтобы они сделали инструмент, и все: они его сделают, но он будет лежать в сторонке, и деньги будут потрачены зря.
Подпишись 👉🏻 @aigentto 🤖
Начну издалека: автоматизация чего-либо — это не новшество: 100+ лет назад человек переходил от лошади к трактору, примерно в то же время — от ручного труда к ткацкому станку и т. д.
Каждый раз производительность росла, и ВВП на душу населения рос, что приводило к увеличению благ на каждого человека. Поэтому страх, что всех уволят, сильно преувеличен, а точнее, это может стать правдой в моменте, но в долгую AI увеличит блага на душу населения, и так или иначе они все равно будут распределены между людьми.
Теперь переместимся чуть ближе в 2014 год: я нанят в "Большой зеленый банк" как Head автоматизации всего QA, то есть автоматизировать все тестирования всех систем компании (200+ очень разношерстных приложений). Тогда еще не было современного AI, хотя эксперимент мы проводили по автоматизации через распознавание экрана с помощью библиотек Google, все на самом деле даже работало, но со скроллами и legacy интерфейсами были проблемы 🤷♂️
Короче, взяли на тот момент уже стандарт BDD+Java+Selenium driver для всего зоопарка Web+Rest API и уникальные всякие штуки для других областей — была там и знаменитая роборука, которая физически тестировала карточки, вставляя их в терминал 🙂
В тот момент проблемой была не технология, хотя с ней были отдельные решаемые сложности. То же самое сейчас - AI не является блокером, в том же паттерне ReAct (читай OpenClaw) может делать 95% дел которые люди делают за компом.
Тогда главной проблемой были люди, а точнее, их интересы: 5 топ-менеджеров компании управляли большими секторами тестирования и с удовольствием выбивали себе огромные бюджеты на найм ручных тестировщиков. Я, по сути, был призван остановить этот бесконечный найм в ручное тестирование и, по факту, стал главным врагом как минимум этих топ-5 менеджеров, а как максимум — всех 2000+ ручных тестировщиков, которые хотели получать зарплату, тыкать кнопки и не очень хотели учить Java и переходить на автоматизацию.
Для понимания накала страстей, в один момент один из этих топ-5 менеджеров то ли в шутку, то ли всерьёз начал на меня кидаться, так сильно я ему мешал 🙂
Я бы хотел сказать, что победили автоматизация и здравый смысл, но так не работает на больших системах, тем не менее через 4 года уровень автоматизации QA вырос с 0 до 30+%, с учетом того, что за это время внедрили еще 10-ки новых приложений и сам объем тестирования вырос в разы. То есть цель автоматизации в 100% была убегающей: вчера 100% — это было 100 000 тестов, завтра — это 200 000 тестов и так далее.
Почему всё-таки получилось сдержать рост ручного труда и, по факту, сэкономить до 300 млн руб. в год на ручном тестировании? Причина была не в том, что я гений автоматизации, причина была не в технологии. Причина была только в том, что мне дали полный ownership, и директор департамента требовал с меня результат, но не лез в то, как и с помощью чего я буду это делать: вначале там была технология и команда из XIX века, я её убрал за один день, несмотря на большую любовь многих к этой технологии и команде, а любовь была потому, что ребята были приятные и никого сильно не напрягали.
И главное — директор департамента дал мне право на внедрение изменений и всегда его поддерживал. Да, конечно, я не шел напролом, я договаривался с теми 5 топ-менеджерами, но у меня было абсолютное право финального решения по всем вопросам автоматизации.
Только полный ownership и право принимать финальные решения по вопросам в моей зоне ответственности позволили добиться большого результата.
Следующими постами я расскажу, как проваливают текущую AI-автоматизацию большие и малые компании. Нельзя просто дать денег и не дать ownership. Нельзя просто нанять ИТшников, чтобы они сделали инструмент, и все: они его сделают, но он будет лежать в сторонке, и деньги будут потрачены зря.
Подпишись 👉🏻 @aigentto 🤖
🔥 Typer: CLI-приложения уровня профи за 5 минут
📌 Typer автоматически создаёт красивый CLI с подсказками, валидацией типов, автодополнением и помощью — всё из type hints. Никаких argparse и click вручную. Идеально для утилит, dev-tools, скриптов автоматизации и внутренних команд.
🛠 pip install typer
Подпишись 👉🏻 @KodduuPython 🤖
import typer
from typing import Optional
app = typer.Typer()
@app.command()
def greet(
name: str = typer.Argument("Мир", help="Кого приветствуем"),
times: int = typer.Option(1, "--times", "-t", help="Сколько раз повторить"),
uppercase: bool = typer.Option(False, "--upper", help="В верхнем регистре")
):
"""Приветствует пользователя с кастомными опциями."""
message = f"Привет, {name}!"
if uppercase:
message = message.upper()
for _ in range(times):
typer.echo(message)
@app.command()
def calculate(
a: int,
b: int,
operation: str = typer.Option("add", help="Операция: add, sub, mul")
):
"""Простой калькулятор через CLI."""
if operation == "add":
result = a + b
elif operation == "sub":
result = a - b
elif operation == "mul":
result = a * b
else:
typer.echo("❌ Неизвестная операция")
raise typer.Exit(code=1)
typer.echo(f"✅ Результат: {result}")
if __name__ == "__main__":
try:
app()
except Exception as e:
typer.echo(f"❌ Ошибка: {e}")
📌 Typer автоматически создаёт красивый CLI с подсказками, валидацией типов, автодополнением и помощью — всё из type hints. Никаких argparse и click вручную. Идеально для утилит, dev-tools, скриптов автоматизации и внутренних команд.
🛠 pip install typer
Подпишись 👉🏻 @KodduuPython 🤖
🔥 Rich: Красивый терминал за 10 секунд
📌 Rich позволяет легко создавать цветной вывод, таблицы, прогресс-бары, статусы и даже markdown в терминале. Один из самых любимых инструментов Python-разработчиков для CLI-приложений, скриптов и дашбордов.
🛠 pip install rich
Подпишись 👉🏻 @KodduuPython 🤖
from rich.console import Console
from rich.table import Table
from rich.progress import track
import time
from typing import List
console = Console()
def process_items(items: List[str]):
"""Пример обработки списка с красивым прогресс-баром и таблицей."""
table = Table(title="Результат обработки")
table.add_column("Элемент", style="cyan")
table.add_column("Статус", style="green")
for item in track(items, description="Обрабатываем элементы..."):
time.sleep(0.3) # имитация работы
status = "✅ Успешно"
table.add_row(item, status)
console.print(table)
if __name__ == "__main__":
try:
data = ["user1.json", "config.yaml", "data.csv", "report.pdf", "logs.txt"]
console.print("[bold magenta]🚀 Запуск обработки файлов[/bold magenta]")
process_items(data)
console.print("[bold green]✅ Все задачи выполнены![/bold green]")
except Exception as e:
console.print(f"[bold red]Ошибка: {e}[/bold red]")
📌 Rich позволяет легко создавать цветной вывод, таблицы, прогресс-бары, статусы и даже markdown в терминале. Один из самых любимых инструментов Python-разработчиков для CLI-приложений, скриптов и дашбордов.
🛠 pip install rich
Подпишись 👉🏻 @KodduuPython 🤖
🔥 httpx: Современная замена requests — быстрее, удобнее и с лучшей обработкой ошибок
📌 httpx — это современный HTTP-клиент с автоматической поддержкой JSON, context manager, таймаутами и отличной обработкой ошибок. Работает и в синхронном, и в асинхронном режиме. Идеально для API, парсинга, микросервисов.
Подпишись 👉🏻 @KodduuPython 🤖
import httpx
from typing import Dict, Any
def get_user_info(user_id: int) -> Dict[str, Any]:
"""Пример безопасного запроса к публичному API с httpx."""
url = f"https://jsonplaceholder.typicode.com/users/{user_id}"
# httpx.Client автоматически управляет соединениями и таймаутами
with httpx.Client(timeout=10.0) as client:
try:
response = client.get(url)
response.raise_for_status() # автоматически бросает исключение при 4xx/5xx
return response.json()
except httpx.HTTPStatusError as e:
print(f"HTTP ошибка {e.response.status_code}: {e.response.text}")
raise
except httpx.RequestError as e:
print(f"Ошибка запроса (таймаут/соединение): {e}")
raise
if __name__ == "__main__":
try:
user = get_user_info(1)
print(f"✅ Пользователь: {user['name']}")
print(f"Email: {user['email']}")
print(f"Город: {user['address']['city']}")
except Exception as e:
print(f"❌ Не удалось получить данные: {e}")
📌 httpx — это современный HTTP-клиент с автоматической поддержкой JSON, context manager, таймаутами и отличной обработкой ошибок. Работает и в синхронном, и в асинхронном режиме. Идеально для API, парсинга, микросервисов.
Подпишись 👉🏻 @KodduuPython 🤖