Зачем нужно делать кастомную базовую Pydantic модель?
Сейчас некоторые со мной не согласятся, но я часто рекомендую делать базовую
Наличие такой глобальной модели позволяет настраивать поведение всех моделей в приложении. Рассмотрю несколько кейсов, когда это может понадобится.
1) Контроль над входными данными.
Например, мы хотим округлять все поля которые называются
P.S.: В коментах подметили, что такой подход неявный, и я с этим согласен. Ничего не мешает для таких целей сделать ещё одну базовую модель (
2) Кастомый энкодер/декодер json.
Пакет
Это происходит из-за того, что операций по (дe)сериализации json в приложении может быть много, и смена библиотеки, в этом случае, дает ощутимый прирост к общей скорости.
В pydantic есть 2 опции в конфиге, которые позволяют изменять поведение энкодера и декодера. Выглядит это так:
Сейчас некоторые со мной не согласятся, но я часто рекомендую делать базовую
pydantic
модель и наследовать все модели от неё.Наличие такой глобальной модели позволяет настраивать поведение всех моделей в приложении. Рассмотрю несколько кейсов, когда это может понадобится.
1) Контроль над входными данными.
Например, мы хотим округлять все поля которые называются
price
до трех знаков после запятой. Сделать это можно так:class CustomBaseModel(BaseModel):Валидаторы дают возможность изменять входящие данные, но это стоит использовать с осторожностью.
@root_validator()
def round_price(cls, data: dict) -> dict:
prices = {k: round(v, 3) for k, v in data.items() if k == "price"}
return {**data, **prices}
P.S.: В коментах подметили, что такой подход неявный, и я с этим согласен. Ничего не мешает для таких целей сделать ещё одну базовую модель (
PriceRoundBaseModel
), наследуясь от нашей базовой СustomBaseModel
и использовать её там, где такое поведение необходимо.2) Кастомый энкодер/декодер json.
Пакет
json
из стандартной библиотеки очень медленный. При необходимости ускорить сервис этот пакет в первую очередь пытаются заменить на что-то побыстрее.Это происходит из-за того, что операций по (дe)сериализации json в приложении может быть много, и смена библиотеки, в этом случае, дает ощутимый прирост к общей скорости.
В pydantic есть 2 опции в конфиге, которые позволяют изменять поведение энкодера и декодера. Выглядит это так:
def orjson_dumps(v, *, default):#pydantic
# orjson.dumps возвращает байты, поэтому нам надо их декодить, чтобы соответствовать сигнатуре json.dumps
return orjson.dumps(v, default=default).decode()
class CustomBaseModel(BaseModel):
class Config:
json_loads = orjson.loads
json_dumps = orjson_dumps
Коробка с питоном
Как раз сегодня искал фреимворк для организации работы консьюмера RabbitMQ и на глаза попался Propan - декларативный фреимворк для работы с очередями сообщений. Для чего это нужно? На базе очередей можно построить асинхронную коммуникацию сервисов, а это…
Автор Propan на Habr'е написал статью "Messaging для чайников. Утилизируем все возможности RabbitMQ на Python", где объясняет основы работы с этим брокером сообщений при помощи своего фреймворка.
Для начинающих - самое то.
#habr #propan #статья
Для начинающих - самое то.
#habr #propan #статья
Как запускать синхронные функции в асинхронном роуте FastAPI?
Иногда так случается, что приходится использовать синхронный код в асинхронном роуте.
Если мы попытаемся вызвать синхронную функцию в асинхронном коде - наш event loop заблокируется и всё "зависнет" до тех пор, пока синхронный код не отработает.
Решений, как это сделать, на самом деле много. Самый простой вариант, который предоставляет FastAPI(а если быть точнее - Starlette, который использует anyio) - функция run_in_threadpool, которая запустит синхронный код в потоке:
А как бы вы решали/решаете такую проблему? Пишите в комментариях 😎 !
#fastapi #anyio
Иногда так случается, что приходится использовать синхронный код в асинхронном роуте.
Если мы попытаемся вызвать синхронную функцию в асинхронном коде - наш event loop заблокируется и всё "зависнет" до тех пор, пока синхронный код не отработает.
Решений, как это сделать, на самом деле много. Самый простой вариант, который предоставляет FastAPI
@app.get("/")Кстати, BackgroundTask использует тот же самый способ, только он не возвращает результат выполнения.
async def my_router():
result = await service.execute()
client = SyncClient()
return await run_in_threadpool(client.execute, data=result)
А как бы вы решали/решаете такую проблему? Пишите в комментариях 😎 !
#fastapi #anyio
Forwarded from Николай Хитров
Релиз
Себастьян закончил обновление
Чейнжлог совсем небольшой получился
https://fastapi.tiangolo.com/release-notes/#01000
p.s. в ближайшее время доберусь до чейнжлога pydantic v2 и сделаю обзорный пост
FastAPI
0.100.0🔥Себастьян закончил обновление
pydantic
-а. Теперь можно насладиться звуком ржавчины и приростом скорости при переходе на новую версию FastAPI
.Чейнжлог совсем небольшой получился
https://fastapi.tiangolo.com/release-notes/#01000
p.s. в ближайшее время доберусь до чейнжлога pydantic v2 и сделаю обзорный пост
Yoyo
В текущих реалиях практически любой сервис использующий реляционную БД не может обойтись без миграций. Так уж сложилось, что в нашем питонячьем мире, в проектах почти всегда можно увидеть ORM (например SQLAlchemy) и пакет, который позволяет управлять миграциями, работающий с конкретной ORM (в случае с Алхимией это alembic).
Но иногда попадаются такие проекты, в которых нам не нужна ORM, по разным причинам. В этом случае, для миграций можно использовать yoyo.
Yoyo - это простой мигратор схем для нашей БД. Миграции здесь записываются в виде скриптов на SQL или на Python.
Сгенерировать папку для миграций и конфиг можно вот так:
Внутри базы yoyo создает таблицу с логом всех операций (
Вот такая вот простая и удобная библиотека :)
Сайт | Sourcehut | PyPI
#библиотека
В текущих реалиях практически любой сервис использующий реляционную БД не может обойтись без миграций. Так уж сложилось, что в нашем питонячьем мире, в проектах почти всегда можно увидеть ORM (например SQLAlchemy) и пакет, который позволяет управлять миграциями, работающий с конкретной ORM (в случае с Алхимией это alembic).
Но иногда попадаются такие проекты, в которых нам не нужна ORM, по разным причинам. В этом случае, для миграций можно использовать yoyo.
Yoyo - это простой мигратор схем для нашей БД. Миграции здесь записываются в виде скриптов на SQL или на Python.
Сгенерировать папку для миграций и конфиг можно вот так:
yoyo init --database sqlite:///mydb.sqlite3 migrationsА теперь создадим миграцию:
yoyo newОпишем SQL для применения миграции (apply) и для её отката (rollback):
from yoyo import stepТеперь можно применить миграцию командой
__depends__ = {}
steps = [
step(
"CREATE TABLE TEST (a int);",
"DROP TABLE TEST"
)
]
yoyo apply
и после откатить её командой yoyo rollback
. Внутри базы yoyo создает таблицу с логом всех операций (
_yoyo_log
), таблицу с применёнными миграциями (_yoyo_migration
), а так же таблицу yoyo_lock
, которая позволяет заблокировать миграции, которые будут идти с нескольких инстансов приложений. Вот такая вот простая и удобная библиотека :)
Сайт | Sourcehut | PyPI
#библиотека
GIL скорее всего уберут из Python!
Руководящий совет объяснил статус PEP 703 (сделать GIL опциональным). Если кратко, то понятно следующее:
— Они намерены принять PEP 703, но всё ещё работают над деталями, предстоит много работы.
— Вероятно, лет через пять сборка без GIL будет ЕДИНСТВЕННОЙ сборкой, так как они не хотят разделять комьюнити на no-GIL и GIL.
— Совет не хочет повторения ситуации с Python 3, поэтому большое внимание будет уделено обратной совместимости.
— Прежде чем отказаться от GIL, они внимательно будут изучать работу комьюнити в этом направлении. Ребята хотят убедиться, что переход будет плавным, а поддержка режима no-GIL будет достаточна.
— Не смотря на все это, совет хочет иметь возможность "дать заднюю", если для комьюнити и языка это принесёт намного больше проблем, чем профита.
Новость просто невероятная. Остается надеяться на комьюнити, будет ли оно готово адаптировать свои библиотеки под этот режим?
#gil
Руководящий совет объяснил статус PEP 703 (сделать GIL опциональным). Если кратко, то понятно следующее:
— Они намерены принять PEP 703, но всё ещё работают над деталями, предстоит много работы.
— Вероятно, лет через пять сборка без GIL будет ЕДИНСТВЕННОЙ сборкой, так как они не хотят разделять комьюнити на no-GIL и GIL.
— Совет не хочет повторения ситуации с Python 3, поэтому большое внимание будет уделено обратной совместимости.
— Прежде чем отказаться от GIL, они внимательно будут изучать работу комьюнити в этом направлении. Ребята хотят убедиться, что переход будет плавным, а поддержка режима no-GIL будет достаточна.
— Не смотря на все это, совет хочет иметь возможность "дать заднюю", если для комьюнити и языка это принесёт намного больше проблем, чем профита.
Новость просто невероятная. Остается надеяться на комьюнити, будет ли оно готово адаптировать свои библиотеки под этот режим?
#gil
Discussions on Python.org
A Steering Council notice about PEP 703 (Making the Global Interpreter Lock Optional in CPython)
Posting for the whole Steering Council, on the subject of @colesbury’s PEP 703 (Making the Global Interpreter Lock Optional in CPython). Thank you, everyone, for responding to the poll on the no-GIL proposal. It’s clear that the overall sentiment is positive…
Появился PEP 723, который предлагает "встраивать"
Предлагается добавить переменную
К примеру, вот так будет выглядеть скрипт, которому для работы нужна библиотека
#pep
pyproject.toml
в однофайловые скрипты. Предлагается добавить переменную
__pyproject__
, которая будет содержать в себе валидный TOML, описывающий метадату скрипта, в том числе как скрипт запускать и какие зависимости необходимы для запуска.К примеру, вот так будет выглядеть скрипт, которому для работы нужна библиотека
requests
и питон 3.11 или выше:__pyproject__ = """PEP прикольный, что-то такое есть в качестве экспериментального RFC в Rust. Из минусов хотел бы отметить то, что автоматическая установка зависимостей может привести к запуску нежелательного кода. Но решение банальное - перед тем как что-то запускать, проверяйте, что вы запускаете.
[project]
requires-python = ">=3.11"
dependencies = [
"requests<3",
]
"""
import requests
resp = requests.get("https://peps.python.org/api/peps.json")
print(resp.json())
#pep
Python Enhancement Proposals (PEPs)
PEP 723 – Inline script metadata | peps.python.org
This PEP specifies a metadata format that can be embedded in single-file Python scripts to assist launchers, IDEs and other external tools which may need to interact with such scripts.
Занимаюсь в рамках петпроекта обработкой текста, появилась потребность проверять на каком языке написан текст.
Сначала я попытался использовать langdetect, но он часто выдавал неправильные результаты. Как правило, плохие результаты выдавались по нескольким причинам:
1. Нет возможности ограничить языки, которые я хотел бы детектить. Мне надо определять всего четыре языка - украинский, русский, английский и немецкий.
2. Часто исследуемый мною текст слишком мал, из-за чего анализ ломался.
По итогу я пошел искать другую библиотеку и нашел lingua, которая успешно справляется с проблемами langdetect.
Важное отличие этой библиотеки от всех остальных в том, что она использует не только статистическую модель для определения языка, а ещё и механизмы, основанные на правилах - сначала определяется алфавит текста, ищутся символы которые уникальны для языка и после этого выбираются языки, на которых возможно написан текст.
Но есть возможность улучшить этот процесс. Можно самому ограничить языки, на которых возможно будет написан текст, а это как раз то, что мне и нужно:
Из-за ограничения языков вероятность совершить ошибку на небольших предложениях сокращается многократно. В добавок ко всему, ребята используют не только триграммы, которые очень часто используют для таких задач, а n-граммы от 1 до 5, из-за чего вероятность предсказания повышается.
Причина такого решения проста - чем короче входной текст, тем меньше n-грамм доступно, а если мы будем проверять триграммами короткие заголовки - будут случаться ошибки.
Ну и база - ограничение количества языков ускоряет работу и уменьшает потребление памяти, а при исследовании огромных текстов - это несомненный плюс.
#nlp #библиотека
Сначала я попытался использовать langdetect, но он часто выдавал неправильные результаты. Как правило, плохие результаты выдавались по нескольким причинам:
1. Нет возможности ограничить языки, которые я хотел бы детектить. Мне надо определять всего четыре языка - украинский, русский, английский и немецкий.
2. Часто исследуемый мною текст слишком мал, из-за чего анализ ломался.
По итогу я пошел искать другую библиотеку и нашел lingua, которая успешно справляется с проблемами langdetect.
Важное отличие этой библиотеки от всех остальных в том, что она использует не только статистическую модель для определения языка, а ещё и механизмы, основанные на правилах - сначала определяется алфавит текста, ищутся символы которые уникальны для языка и после этого выбираются языки, на которых возможно написан текст.
Но есть возможность улучшить этот процесс. Можно самому ограничить языки, на которых возможно будет написан текст, а это как раз то, что мне и нужно:
from lingua import Language, LanguageDetectorBuilder
languages = [Language.ENGLISH, Language.RUSSIAN, Language.GERMAN, Language.UKRAINIAN]
detector = LanguageDetectorBuilder.from_languages(*languages).build()
print(detector.detect_language_of("Hello from box with python!")) # Language.ENGLISH
print(detector.detect_language_of("Привет от коробки с питоном!")) # Language.RUSSIAN
Из-за ограничения языков вероятность совершить ошибку на небольших предложениях сокращается многократно. В добавок ко всему, ребята используют не только триграммы, которые очень часто используют для таких задач, а n-граммы от 1 до 5, из-за чего вероятность предсказания повышается.
Причина такого решения проста - чем короче входной текст, тем меньше n-грамм доступно, а если мы будем проверять триграммами короткие заголовки - будут случаться ошибки.
Ну и база - ограничение количества языков ускоряет работу и уменьшает потребление памяти, а при исследовании огромных текстов - это несомненный плюс.
#nlp #библиотека
PyPI
langdetect
Language detection library ported from Google's language-detection.
Немного девопсовский пост, так как на предыдущем месте работы я много админил линукса.
Автоматизация - один из столпов работы любого админа, так как подготавливать сервера руками - занятие тяжелое и трудозатратное.
Для этого я всегда выбирал Ansible - это довольно простой инструмент, который позволяет настраивать сервера из специальных yaml конфигов, которые называются плейбуками.
Но какой бы вы инструмент не выбрали, рано или поздно конфигурация будет усложняться, а плейбуков/скриптов станет много. В какой-то момент всё это может сломаться, поэтому любую автоматизацию надо тестировать.
Когда я админил, команда не хотела полностью завязываться на Ansible (соответственно Molecule отпадает), решено было искать инструмент, который позволял бы тестировать состояние сервера после работы любой автоматизации.
И я нашел такой инструмент, имя ему - testinfra. Это плагин для pytest, который позволяет лаконично описывать тесты проверяющие состояние сервера.
Например, мы написали автоматизацию, которая устанавливает nginx. Проверим, что он установлен:
Напоследок, вот вам еще кейс использования: одно время при помощи testinfra я тестировал правильность сборки контейнеров - все ли есть права, запустился ли сервис, в порядке ли конфиги и так далее.
#devops #библиотека
Автоматизация - один из столпов работы любого админа, так как подготавливать сервера руками - занятие тяжелое и трудозатратное.
Для этого я всегда выбирал Ansible - это довольно простой инструмент, который позволяет настраивать сервера из специальных yaml конфигов, которые называются плейбуками.
Но какой бы вы инструмент не выбрали, рано или поздно конфигурация будет усложняться, а плейбуков/скриптов станет много. В какой-то момент всё это может сломаться, поэтому любую автоматизацию надо тестировать.
Когда я админил, команда не хотела полностью завязываться на Ansible (соответственно Molecule отпадает), решено было искать инструмент, который позволял бы тестировать состояние сервера после работы любой автоматизации.
И я нашел такой инструмент, имя ему - testinfra. Это плагин для pytest, который позволяет лаконично описывать тесты проверяющие состояние сервера.
Например, мы написали автоматизацию, которая устанавливает nginx. Проверим, что он установлен:
def test_nginx_is_installed(host):А теперь проверим, что сервис с ним запущен:
nginx = host.package("nginx")
assert nginx.is_installed
def test_nginx_running_and_enabled(host):Самое важное - для него существует много connection backend'ов, которые позволяют подключаться к серверам для теста как по SSH (через paramiko), так и используя инвентарь Ansible. Так же есть бекенды для docker/podman/salt/kubectl/openshift/winrm/lxc - обо всём этом можно почитать здесь.
nginx = host.service("nginx")
assert nginx.is_running
assert nginx.is_enabled
Напоследок, вот вам еще кейс использования: одно время при помощи testinfra я тестировал правильность сборки контейнеров - все ли есть права, запустился ли сервис, в порядке ли конфиги и так далее.
#devops #библиотека
Тианголо (создатель FastAPI) предложил новый PEP 727, который позволяет стандартизировать механизм документирования параметров.
Причина проста - существует много псевдо-стандартов по форматированию параметров в docstring (например свои стандарты есть у numpy, гугла, много их!), но не все редакторы/IDE имеют возможность поддерживать эти "микроязыки". Он предлагает стандартизировать подход, используя существующий мощный инструмент в виде аннотаций типов.
Основное предложение - добавление в
А вот как это будет выглядеть:
Выглядит интересно, но важно понимать - автор пытается создать ещё один стандарт. Поддержит ли его комьюнити и уйдет ли PEP в работу? Остается только гадать.
#pep
Причина проста - существует много псевдо-стандартов по форматированию параметров в docstring (например свои стандарты есть у numpy, гугла, много их!), но не все редакторы/IDE имеют возможность поддерживать эти "микроязыки". Он предлагает стандартизировать подход, используя существующий мощный инструмент в виде аннотаций типов.
Основное предложение - добавление в
typing
новой функции doc
, которая принимает единственный параметр documentation
. Ожидается, что эта функция будет использоваться вместе с Annotated
.А вот как это будет выглядеть:
def create_user(Тианголо заранее позаботился и о старых версиях - он не стал выдумывать новый синтаксис, так же предлагается добавить
lastname: Annotated[str, doc("The **last name** of the newly created user")],
firstname: Annotated[str | None, doc("The user's **first name**")] = None,
) -> Annotated[User, doc("The created user after saving in the database")]:
"""
Create a new user in the system, it needs the database connection to be already
initialized.
"""
pass
doc()
в пакет typing_extensions
, который используют старые версии питона для исключения проблем с совместимостью. Выглядит интересно, но важно понимать - автор пытается создать ещё один стандарт. Поддержит ли его комьюнити и уйдет ли PEP в работу? Остается только гадать.
#pep
Python Enhancement Proposals (PEPs)
PEP 727 – Documentation in Annotated Metadata | peps.python.org
This PEP proposes a standardized way to provide documentation strings for Python symbols defined with Annotated using a new class typing.Doc.
Недавно мой знакомый @nesclass (можете ему писать по теме доклада) выступал c докладом "Асинхронное варение MongoDB в Python" на Pytup.
Автор объяснил наглядно в чем различие реляционных баз от документно-ориентированных, немного рассказал про подходы работы с БД, затронул тему object mapper'ов и много рассказал про Beanie - ODM для работы с MongoDB (про которую я писал) и саму монгу.
Доклад отлично подойдет для тех, кто хочет ознакомиться с этим инструментом и послушать про подводные камни, с которыми часто встречаются новички.
#посмотреть
Автор объяснил наглядно в чем различие реляционных баз от документно-ориентированных, немного рассказал про подходы работы с БД, затронул тему object mapper'ов и много рассказал про Beanie - ODM для работы с MongoDB (про которую я писал) и саму монгу.
Доклад отлично подойдет для тех, кто хочет ознакомиться с этим инструментом и послушать про подводные камни, с которыми часто встречаются новички.
#посмотреть
YouTube
Асинхронное варение MongoDB в Python - Даниил Неслуховский, старший разработчик, Элитриум
Если вам приходилось работать с bash, например парсить логи, вы наверняка видели или использовали команды следующего вида:
Символ
В Elixir есть оператор конвейера
Согласитесь, так удобнее работать с коллекциями, особенно там где данных много и их хочется как-то отфильтровать. В случае использования конвейеров нам больше не надо строить громоздкие циклы, а код прост и понятен.
Если вам интересно. как можно сделать такое в Python, то для вас есть библиотека Pipe. Реализация очень простая - библиотека добавляет класс Pipe который переопределяет оператор
Например, вот так мы можем получить сумму товаров, цена которых больше тысячи:
cat app.log | grep 'exception' | awk '{ print $2 }'
Здесь мы последовательно считываем содержимое файла app.log
, фильтруем по подстроке exception
и выводим вторую колонку. Символ
|
, которая разделяет команды называется "пайпом" - он перенаправляет вывод из одной команды в другую, а вся эта конструкция в целом называется конвейером, и она очень часто используется в функциональном программировании.В Elixir есть оператор конвейера
|>
который позволяет передавать результат выполнения левого выражения в правое. Это позволяет делать вот такие штуки:1..10Здесь мы генерируем список от 1 до 10, умножаем каждый элемент на 2 и фильтруем только те, которые больше 10.
|> Enum.map(fn x -> x * 2 end)
|> Enum.filter(fn x -> x > 10 end)
[12, 14, 16, 18, 20]
Согласитесь, так удобнее работать с коллекциями, особенно там где данных много и их хочется как-то отфильтровать. В случае использования конвейеров нам больше не надо строить громоздкие циклы, а код прост и понятен.
Если вам интересно. как можно сделать такое в Python, то для вас есть библиотека Pipe. Реализация очень простая - библиотека добавляет класс Pipe который переопределяет оператор
|
. Далее мы оборачиваем наши функции в этот класс и можем строить конвейеры!Например, вот так мы можем получить сумму товаров, цена которых больше тысячи:
from typing import NamedTuple
from pipe import select, where
class Product(NamedTuple):
name: str
price: int
products = [Product("choco", 123), Product("auto", 10000), Product("photo", 1200)]
sum(
products
| select(lambda product: product.price)
| where(lambda x: x > 1000)
) # 11200
#библиотекаGitHub
GitHub - JulienPalard/Pipe: A Python library to use infix notation in Python
A Python library to use infix notation in Python. Contribute to JulienPalard/Pipe development by creating an account on GitHub.
Коробка с питоном
Как раз сегодня искал фреимворк для организации работы консьюмера RabbitMQ и на глаза попался Propan - декларативный фреимворк для работы с очередями сообщений. Для чего это нужно? На базе очередей можно построить асинхронную коммуникацию сервисов, а это…
Помните, я рассказывал про такой фреимворк как Propan? В общем, программа Propan удаляется на смену Propan пришел FastStream, и весь новый функционал будет попадать в него.
Первой моей реакцией было "што" и "зачем", ведь на первый взгляд может показаться, что поменялись только орга и название. Давайте разбираться.
Во-первых, за фреимворком стоит не только сам Lancetnik, а целая команда из AirtAI, что является очень сильным усилением со стороны как разработки, так и поддержки.
Второе, FastKafka переходит в такой же статус как и Propan. Всё по той же причине - новый функционал будут добавлять в FastStream.
В свою очередь FastStream - это фреимворк, базированный на идеях FastKafka и Propan, который хочет взять от них самое лучшее и создать единый способ для написания сервисов, работающих с очередями.
Третье, что показалось мне важным, разработчик Propan признаётся, что сделать унифицированный RPC для всех брокеров (например для Kafka) - задача сложная, особенно когда брокер by design плохо рассчитан на такую функциональность. Всё сводилось к тому, что тот самый простой высокоуровневый интерфейс плохо скрывал недостатки реализации, поэтому в FastStream от него отказались.
Ещё генерацию темплейтов удалили, теперь проект можно генерировать при помощи cookiecutter.
А что нового уже принёс FastStream?
В первую очередь, мне понравился механизм фильтров. Ещё добавили кастомную сериализацию - по умолчанию FastStream работает с Json, но если у вас Protobuf, Avro или msgpack - больше никаких проблем нет, можно добавить собственную логику для сериализации.
Отдельно хотел бы выделить систему мидлварей - теперь трассировку, логи, обогащение сообщений метаинформацией делать намного проще.
Очень надеюсь, что проект будет развиваться семимильными шагами, ведь идеи FastKafka и Propan мне очень сильно понравились, а сам Propan я очень часто рекомендовал знакомым.
P.S. Оказывается кастомная сериализация уже была.
#библиотека
Первой моей реакцией было "што" и "зачем", ведь на первый взгляд может показаться, что поменялись только орга и название. Давайте разбираться.
Во-первых, за фреимворком стоит не только сам Lancetnik, а целая команда из AirtAI, что является очень сильным усилением со стороны как разработки, так и поддержки.
Второе, FastKafka переходит в такой же статус как и Propan. Всё по той же причине - новый функционал будут добавлять в FastStream.
В свою очередь FastStream - это фреимворк, базированный на идеях FastKafka и Propan, который хочет взять от них самое лучшее и создать единый способ для написания сервисов, работающих с очередями.
Третье, что показалось мне важным, разработчик Propan признаётся, что сделать унифицированный RPC для всех брокеров (например для Kafka) - задача сложная, особенно когда брокер by design плохо рассчитан на такую функциональность. Всё сводилось к тому, что тот самый простой высокоуровневый интерфейс плохо скрывал недостатки реализации, поэтому в FastStream от него отказались.
Ещё генерацию темплейтов удалили, теперь проект можно генерировать при помощи cookiecutter.
А что нового уже принёс FastStream?
В первую очередь, мне понравился механизм фильтров. Ещё добавили кастомную сериализацию - по умолчанию FastStream работает с Json, но если у вас Protobuf, Avro или msgpack - больше никаких проблем нет, можно добавить собственную логику для сериализации.
Отдельно хотел бы выделить систему мидлварей - теперь трассировку, логи, обогащение сообщений метаинформацией делать намного проще.
Очень надеюсь, что проект будет развиваться семимильными шагами, ведь идеи FastKafka и Propan мне очень сильно понравились, а сам Propan я очень часто рекомендовал знакомым.
P.S. Оказывается кастомная сериализация уже была.
#библиотека
GitHub
GitHub - airtai/faststream: FastStream is a powerful and easy-to-use Python framework for building asynchronous services interacting…
FastStream is a powerful and easy-to-use Python framework for building asynchronous services interacting with event streams such as Apache Kafka, RabbitMQ, NATS and Redis. - airtai/faststream
На второе октября намечен релиз Python 3.12, поэтому Никита Соболев (opensource разработчик и контрибьютор в сpython) рассказывает про новинки в новой версии и чуть затрагивает то, что ожидает нас в 3.13.
Рекомендую посмотреть, чтобы оставаться в теме новых обновлений.
#посмотреть
Рекомендую посмотреть, чтобы оставаться в теме новых обновлений.
#посмотреть
YouTube
«Новинки в Python 3.12 и даже немного про 3.13», Никита Соболев
«Окей, Никита, что нового в Python?»
Еще одни спикер #GPDays2023 Никита Соболев – Open Source разработчик и любитель Python рассказал о чистке stdlib, PEP 695, новом синтаксисе для типизации, а также uops из Python 3.13:
01:19 Что нового в новом Python…
Еще одни спикер #GPDays2023 Никита Соболев – Open Source разработчик и любитель Python рассказал о чистке stdlib, PEP 695, новом синтаксисе для типизации, а также uops из Python 3.13:
01:19 Что нового в новом Python…
Недавно пришлось писать конвертор который транслировал Markdown в довольно специфичный формат.
Была следующая идея - мне нужен парсер, который перегонит Markdown в синтаксическое дерево, которое я буду обходить.
С обычным python-markdown в этом плане банально неудобно работать - у него нет простого и расширяемого API (как минимум), который бы позволял решить мою задачу.
А вот у mistletoe такое API есть. Например, вот так выглядит рендерер markdown в jira:
#библиотека
Была следующая идея - мне нужен парсер, который перегонит Markdown в синтаксическое дерево, которое я буду обходить.
С обычным python-markdown в этом плане банально неудобно работать - у него нет простого и расширяемого API (как минимум), который бы позволял решить мою задачу.
А вот у mistletoe такое API есть. Например, вот так выглядит рендерер markdown в jira:
class JiraRenderer(BaseRenderer):Ещё mistletoe можно использовать как утилиту. Например, вот так markdown-файл можно перевести в тот же формат Jira:
def render_strong(self, token):
template = '*{}*'
return template.format(self.render_inner(token))
def render_emphasis(self, token):
template = '_{}_'
return template.format(self.render_inner(token))
mistletoe foo.md --renderer mistletoe.contrib.jira_renderer.JiraRendererПоэтому, если вам нужна небольшая, но расширяемая библиотека для работы с markdown - берите её, не прогадаете.
#библиотека
Пока я спал, руководящий совет языка принял PEP 703 (Making the Global Interpreter Lock Optional in CPython).
Кратко о том, о чём говорится в посте:
1. Руководящему совету ясно, что несмотря на все проблемы и недостатки потоков, nogil будет полезен для Python, так как позволит находить более масштабируемые решения.
2. В то же время, они не уверены, получится ли убрать GIL не сломав при этом обратную совместимость - всё же не хотелось бы терять десятилетия развития базы пакетов. Существующая пакетная экосистема - это одна из сильных сторон языка, как и простая интеграция библиотек на C c CPython.
3. Оценить влияние nogil без реализации сложно, поэтому nogil должен выпускаться в составе регулярных релизов и не обязательно он там должен быть по-умолчанию.
4. Это всё ещё не гарантированная история. Если что-то пойдет не так - от изменений откажутся. Развёртывание должно быть постепенным и наиболее плавным.
5. Выкатка будет происходить в 3 фазы, которые возможно изменятся:
- В первой фазе nogil сделают возможным таргетом при сборке, чтобы разработчики могли тестировать свои пакеты.
- Во второй фазе, когда изменения в API и ABI будут сформированы, а поддержка nogil от сообщества будет достаточной, nogil-сборку добавлят как "поддерживаемую, но не по умолчанию".
- В третьей фазе nogil-сборку сделают сборкой "по-умолчанию", а от gil-сборки будут отказываться.
6. При успешной реализации nogil, ожидается падение производительности на 10-15% в худшем случае.
#pep
Кратко о том, о чём говорится в посте:
1. Руководящему совету ясно, что несмотря на все проблемы и недостатки потоков, nogil будет полезен для Python, так как позволит находить более масштабируемые решения.
2. В то же время, они не уверены, получится ли убрать GIL не сломав при этом обратную совместимость - всё же не хотелось бы терять десятилетия развития базы пакетов. Существующая пакетная экосистема - это одна из сильных сторон языка, как и простая интеграция библиотек на C c CPython.
3. Оценить влияние nogil без реализации сложно, поэтому nogil должен выпускаться в составе регулярных релизов и не обязательно он там должен быть по-умолчанию.
4. Это всё ещё не гарантированная история. Если что-то пойдет не так - от изменений откажутся. Развёртывание должно быть постепенным и наиболее плавным.
5. Выкатка будет происходить в 3 фазы, которые возможно изменятся:
- В первой фазе nogil сделают возможным таргетом при сборке, чтобы разработчики могли тестировать свои пакеты.
- Во второй фазе, когда изменения в API и ABI будут сформированы, а поддержка nogil от сообщества будет достаточной, nogil-сборку добавлят как "поддерживаемую, но не по умолчанию".
- В третьей фазе nogil-сборку сделают сборкой "по-умолчанию", а от gil-сборки будут отказываться.
6. При успешной реализации nogil, ожидается падение производительности на 10-15% в худшем случае.
#pep
Discussions on Python.org
PEP 703 (Making the Global Interpreter Lock Optional in CPython) acceptance
(Posted for the whole Steering Council.) As we’ve announced before, the Steering Council has decided to accept PEP 703 (Making the Global Interpreter Lock Optional in CPython) . We want to make it clear why, and under what expectations we’re doing so. It…
Коробка с питоном
Если обычного itertools вам мало, то можно использовать more-itertools. Эта библиотека добавляет огромное количество функций для работы с итераторами. На практике всеми ими не всегда пользуются, поэтому я выделю некоторые из тех, которые сам использую часто.…
На сегодня расскажу ещё пару рецептов с
1)
2) Получить последний элемент можно при помощи
Ещё есть
3)
4) Ну и в конце про
#itertools #more_itertools #библиотека #рецепт
more_itertools
.1)
map_if
работает как обычный map
, но применяет функцию на элемент только если оно попадает под условие. Например, вот так мы можем возвести в квадрат только те числа, которые делятся на 2 нацело:example = [1, 2, 3, 4, 5, 6, 7, 8]
list(map_if(example, lambda x: x % 2 == 0, lambda x: x * x)) # [1, 4, 3, 16, 5, 36, 7, 64]
2) Получить последний элемент можно при помощи
last
. Возникает вопрос а зачем он существует, если можно указать sequence[-1]
? Ответом является то, что last
позволяет указать, что ему возвращать, если элементов в коллекции нет:last([1, 2, 3]) # Очевидно получим 3
last([], 0) # Список пустой, но получим 0
[][-1] # Получим IndexError
Ещё есть
first
- как понятно из названия, он получает первый элемент.3)
map_except
тоже работает как map
, но умеет игнорировать ошибки. Например, мы хотим получить только те элементы, которые получилось привести к целому числу:example = [1, "1", "2", "test", "three", object, 4.0]
list(map_except(int, example, ValueError, TypeError)) # [1, 1, 2, 4]
4) Ну и в конце про
take
- он просто берет N элементов из итерируемого объекта:example = range(10)
take(3, example) # [0, 1, 2]
take(20, example) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] - если больше, возьмет доступные
#itertools #more_itertools #библиотека #рецепт
В одном чатике встретил проект fakeredis, реализующий Redis-сервер на питоне, который можно использовать для тестов. Очевидно, чтобы не таскать для тестов настоящий Redis.
Поддерживаются практически все стандартные команды, которые я встречал для работы с типами/коллекциями (список здесь). Есть не полная поддержка JSON, поиска, time series.
Если каких-то команд не хватает, автор оставил гайд, как её сделать. Ну а если сделаете - законтрибутьте в опенсорс, полезное дело всё таки!
#библиотека
Поддерживаются практически все стандартные команды, которые я встречал для работы с типами/коллекциями (список здесь). Есть не полная поддержка JSON, поиска, time series.
Если каких-то команд не хватает, автор оставил гайд, как её сделать. Ну а если сделаете - законтрибутьте в опенсорс, полезное дело всё таки!
#библиотека
GitHub
GitHub - cunla/fakeredis-py: Implementation of Redis in python without having a Redis server running. Fully compatible with using…
Implementation of Redis in python without having a Redis server running. Fully compatible with using redis-py. - cunla/fakeredis-py
Forwarded from Питонические атаки
PSF и JetBrains запустили своё ежегодное исследование Python Developers Survey 2023. Погнали заполнять! 👇
https://survey.alchemer.com/s3/7554174/python-developers-survey-2023
Через год, когда подведут результаты, будет повод написать пост, типа такого 😅
https://survey.alchemer.com/s3/7554174/python-developers-survey-2023
Через год, когда подведут результаты, будет повод написать пост, типа такого 😅
Alchemer
Python Developers Survey 2023
The official Python Developers Survey 2023. Join and contribute to the community knowledge!
Forwarded from Николай Хитров
Да, у нас есть тесты. А толку?
Супер-мега-гига экслюзивный доступ к записи моего доклада с прошедшего PiterPy. Организаторы разрешили выложить не дожидаясь следующего года. Получилось как всегда холиварно, не всё всем может понравиться, но как минимум советую присмотреться к библиотечкам и статьям/докладам из полезных ссылок. Там немного, но самое годное из того что знаю по этой теме. Куда кидать помидоры и звездочки вы знаете 🙂🙃
https://youtu.be/liECQCFGfkE
Супер-мега-гига экслюзивный доступ к записи моего доклада с прошедшего PiterPy. Организаторы разрешили выложить не дожидаясь следующего года. Получилось как всегда холиварно, не всё всем может понравиться, но как минимум советую присмотреться к библиотечкам и статьям/докладам из полезных ссылок. Там немного, но самое годное из того что знаю по этой теме. Куда кидать помидоры и звездочки вы знаете 🙂🙃
https://youtu.be/liECQCFGfkE
YouTube
Николай Хитров — Да, у нас есть тесты. А толку?
Подробнее о конференции PiterPy: https://jrg.su/QZ6wK1
— —
Скачать презентацию с сайта PiterPy — https://jrg.su/eCB2vc
Кандидаты часто спрашивают на собеседованиях, принято ли в команде писать тесты. И ответ в духе «да, мы пишем тесты» дает некоторую надежду…
— —
Скачать презентацию с сайта PiterPy — https://jrg.su/eCB2vc
Кандидаты часто спрашивают на собеседованиях, принято ли в команде писать тесты. И ответ в духе «да, мы пишем тесты» дает некоторую надежду…