Коробка с питоном
Я заметил, что редко использую функции из itertools, в основном когда нужно произвести какие-то "красивые" шаманства. Теперь будем вспоминать саму библиотеку вместе, естественно с примерами :) Сам модуль itertools это набор из эффективных и быстрых по памяти…
repeat(object: T, times: Optional[int] = None) -> Iterable[T]
Создает итератор который возвращает объект снова и снова. Можно указать параметр times, который вернет объект заданное количество раз и завершит работу итератора:>>> first = repeat("hehe", 3)Очень часто repeat используют чтобы по быстрому сгенерировать коллекцию из элементов:
>>> next(first)
'hehe'
>>> next(first)
'hehe'
>>> next(first)
'hehe'
>>> next(first)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> list(repeat(10, 10))#itertools #std
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
Там у Python 3.11 сегодня релиз, пройдемся по изменениям. Разделю пост на 2 части, сначала расскажу про всё остальное, а потом про typing, который снова прокачали.
1) Теперь Питон быстрее на 10-60% чем предыдущая версия. Почему такой разброс и где что ускорилось можно почитать здесь.
2) Exception Groups и *except. За это отвечает PEP 654, теперь есть возможность возбуждать и обрабатывать группы исключений. Судя по PEP сделано в основном для асинхронщины (
3) Для Exception появилась возможность добавлять примечания (notes). Теперь можно после обработки исключения добавить какую-то дополнительную информацию. Почитать подробно можно в PEP 678
4) Многие ждали и дождались - теперь в стандартной библиотеке есть tomllib, который позволяет работать с форматом TOML. Мотивация - его использует куча инструментов (black, mypy, pytest и т.д.), при чем каждый либо использует свою наколеночную реализацию, либо какую-то другую библиотеку. А тут решили стандартизировать, теперь это PEP 680.
5) Трейсбеки снова улучшили, теперь интерпретатор умеет показывать где именно находится ошибка, а не писать строку, где она произошла. Посмотреть на то как это выглядит можно в PEP 657.
6) Объявлены устаревшими следующие модули: aifc, audioop, cgi (за что?) и cgitb, chunk, crypt, imghdr (пользуйтесь PIL), mailcap, msilib, nis, nntplib, ossaudiodev, pipes (давно есть subprocess), sndhdr, spwd, sunau, telnetlib (вот этого я точно не могу понять), uu, xdrlib. Их удалят в 3.13.
А самому почитать об изменениях можно здесь.
1) Теперь Питон быстрее на 10-60% чем предыдущая версия. Почему такой разброс и где что ускорилось можно почитать здесь.
2) Exception Groups и *except. За это отвечает PEP 654, теперь есть возможность возбуждать и обрабатывать группы исключений. Судя по PEP сделано в основном для асинхронщины (
asyncio.gather
), колбеков и операций с несколькими попытками.3) Для Exception появилась возможность добавлять примечания (notes). Теперь можно после обработки исключения добавить какую-то дополнительную информацию. Почитать подробно можно в PEP 678
4) Многие ждали и дождались - теперь в стандартной библиотеке есть tomllib, который позволяет работать с форматом TOML. Мотивация - его использует куча инструментов (black, mypy, pytest и т.д.), при чем каждый либо использует свою наколеночную реализацию, либо какую-то другую библиотеку. А тут решили стандартизировать, теперь это PEP 680.
5) Трейсбеки снова улучшили, теперь интерпретатор умеет показывать где именно находится ошибка, а не писать строку, где она произошла. Посмотреть на то как это выглядит можно в PEP 657.
6) Объявлены устаревшими следующие модули: aifc, audioop, cgi (за что?) и cgitb, chunk, crypt, imghdr (пользуйтесь PIL), mailcap, msilib, nis, nntplib, ossaudiodev, pipes (давно есть subprocess), sndhdr, spwd, sunau, telnetlib (вот этого я точно не могу понять), uu, xdrlib. Их удалят в 3.13.
А самому почитать об изменениях можно здесь.
Коробка с питоном
Там у Python 3.11 сегодня релиз, пройдемся по изменениям. Разделю пост на 2 части, сначала расскажу про всё остальное, а потом про typing, который снова прокачали. 1) Теперь Питон быстрее на 10-60% чем предыдущая версия. Почему такой разброс и где что ускорилось…
Немного с запозданием, но поговорим про новые фичи в typing.
1)
Есть такой специальный класс как
Теперь для описания полей в нём добавили три вещи:
1.
2.
3. Аргумент
Почитать подробнее о нём можно вот тут
2) Self.
Ликуйте, господа, мы дождались! Больше никаких костылей с TypeVar!
Аннотация
3) LiteralString.
Относительно этого тайпхинта строки бывают двух типов - литеральные строки и произвольные строки. К литеральным строкам относятся константы, к произвольным - всё остальное. Данный тип указывает, что строка должна быть первого типа, на остальное оно будет ругаться. Вот пример:
4) Data class transforms
Декоратор который декорирует класс, метакласс или функцию которые являются декоратором. Получившийся декоратор умеет показывать тайпчекеру что декорируемый объект имеет фичи как у датакласса. Причина создания такой штуки проста - нет стандартного пути обозначения, что какой-то объект имеет свойства, присущие датаклассу. Привет Pydantic! PEP 681 читать здесь.
5) Вариативные дженерики.
Есть такая штука как
Зачем это нужно: мы все знаем, что всякие датасотонисты любят наш питон из-за обилия всяких инструментов по типу NumPy или Pandas. Вариативные дженерики позволяют параметризировать структуры, которые подобны массивам, что в свою очередь позволяет находить ошибки при операции с этими структурами тайпчекеру.
PEP 646 читать здесь.
#pep
1)
NotRequired
и Required поля в TypedDict
.Есть такой специальный класс как
TypedDict
- он позволяет добавить тайпхинты к словарю.Теперь для описания полей в нём добавили три вещи:
1.
NotRequired
- показывает, что данного поля может и не быть в словаре.2.
Required
- показывает, что данное поле обязательно должно быть в словаре3. Аргумент
total
- если его значение ложно, то все поля в этом классе будут отмечены как NotRequired
. По умолчанию оно истинно.Почитать подробнее о нём можно вот тут
2) Self.
Ликуйте, господа, мы дождались! Больше никаких костылей с TypeVar!
Аннотация
Self
показывает что мы хотим вернуть инстанс текущего класса. Выглядит это как-то так:class MyLock:Простенько и лаконично. Вот PEP 673.
def __enter__(self) -> Self:
self.lock()
return self
3) LiteralString.
Относительно этого тайпхинта строки бывают двух типов - литеральные строки и произвольные строки. К литеральным строкам относятся константы, к произвольным - всё остальное. Данный тип указывает, что строка должна быть первого типа, на остальное оно будет ругаться. Вот пример:
def run_query(sql: LiteralString) -> ...Исходя из примера видно, что использоваться это будет во всяких функциях, которые выполняют, например, SQL запросы или CLI-утилитах не давая на уровне тайпчекера засунуть в функцию очередной
...
def caller(
arbitrary_string: str,
query_string: LiteralString,
table_name: LiteralString,
) -> None:
run_query("SELECT * FROM students") # ok
run_query(query_string) # ok
run_query("SELECT * FROM " + table_name) # ok
run_query(arbitrary_string) # type checker error
run_query( # type checker error
f"SELECT * FROM students WHERE name = {arbitrary_string}"
)
rm -rf
. А PEP 675 можно почитать здесь.4) Data class transforms
Декоратор который декорирует класс, метакласс или функцию которые являются декоратором. Получившийся декоратор умеет показывать тайпчекеру что декорируемый объект имеет фичи как у датакласса. Причина создания такой штуки проста - нет стандартного пути обозначения, что какой-то объект имеет свойства, присущие датаклассу. Привет Pydantic! PEP 681 читать здесь.
5) Вариативные дженерики.
Есть такая штука как
TypeVar
- она позволяет создавать дженерик параметризированный одним типом. А если нам нужно параметризировать произвольное количество типов? Теперь появился TypeVarTuple
, который решает эту проблему.Зачем это нужно: мы все знаем, что всякие датасотонисты любят наш питон из-за обилия всяких инструментов по типу NumPy или Pandas. Вариативные дженерики позволяют параметризировать структуры, которые подобны массивам, что в свою очередь позволяет находить ошибки при операции с этими структурами тайпчекеру.
PEP 646 читать здесь.
#pep
О работе с PostgreSQL JSONB в SQLAlchemy
JSON поля в PostgreSQL - это действительно удобный способ хранения данных, наряду с реляционной моделью. Они могут понадобиться там, где нужно произвести денормализацию данных для ускорения работы или для хранения гетерогенных данных.
Алхимия поддерживает работу с JSON-полями нативно, поэтому мы можем добавлять эти поля в свои модельки. Но есть пара нюансов, связанных с тем, каким образом алхимия проверяет изменения в этих полях.
Допустим, есть у нас вот такой класс:
Внимательно прочитаем документацию SQLAlchemy и найдем вот такой забавный пункт: The JSON type, when used with the SQLAlchemy ORM, does not detect in-place mutations to the structure. То есть, при изменения структуры нашего объекта Алхимия не понимает, произошло ли какое-то изменение или нет.
Есть 2 решения этой проблемы:
1) Использовать класс MutableDict, если у нас нет вложенности в JSONB объектах:
Просто оборачиваем этой штукой наш тип в модели и радуемся жизни. Выглядит это как-то так:
В данном случае наше поле будет выглядить как-то так:
1) Adding mutability to json
2) Mutation tracking
3) Mutation tracking in nested JSON structures using SQLAlchemy
#sqlalchemy #рецепт
JSON поля в PostgreSQL - это действительно удобный способ хранения данных, наряду с реляционной моделью. Они могут понадобиться там, где нужно произвести денормализацию данных для ускорения работы или для хранения гетерогенных данных.
Алхимия поддерживает работу с JSON-полями нативно, поэтому мы можем добавлять эти поля в свои модельки. Но есть пара нюансов, связанных с тем, каким образом алхимия проверяет изменения в этих полях.
Допустим, есть у нас вот такой класс:
class Config(Base):
id = Column(Integer, primary_key=True)
config = Column(JSONB)
tablename = 'config'
А теперь попытаемся добавить запись и изменить её:cfg = Config(
id=1,
config={'some_const': 1}
)
session.add(cfg)
session.commit()
cfg.config['test'] = 2
session.add(cfg)
session.commit()
# упадёт с assertion error
assert cfg.config['test'] == 2
Почему оно упадёт с assertion error? Внимательно прочитаем документацию SQLAlchemy и найдем вот такой забавный пункт: The JSON type, when used with the SQLAlchemy ORM, does not detect in-place mutations to the structure. То есть, при изменения структуры нашего объекта Алхимия не понимает, произошло ли какое-то изменение или нет.
Есть 2 решения этой проблемы:
1) Использовать класс MutableDict, если у нас нет вложенности в JSONB объектах:
Просто оборачиваем этой штукой наш тип в модели и радуемся жизни. Выглядит это как-то так:
...2) Используем библиотеку sqlalchemy-json, если у нас есть вложенность:
config = Column(MutableDict.as_mutable(JSONB))
В данном случае наше поле будет выглядить как-то так:
from sqlalchemy_json import mutable_json_typeСсылочки:
...
config = Column(mutable_json_type(dbtype=JSONB, nested=True))
1) Adding mutability to json
2) Mutation tracking
3) Mutation tracking in nested JSON structures using SQLAlchemy
#sqlalchemy #рецепт
Ежегодный опрос питонистов от JetBrains начался!
Зачем он нужен: каждый год JetBrains делает опрос для понимания, что из себя представляет Python разработка сейчас - что люди на нём кодят, что используют и так далее.
Опрос занимает 10-15 минут, а для дополнительной мотивации джеты подарят 20 случайным респондентам 100$ Amazon Gift Card!
Пройти можно тут.
Зачем он нужен: каждый год JetBrains делает опрос для понимания, что из себя представляет Python разработка сейчас - что люди на нём кодят, что используют и так далее.
Опрос занимает 10-15 минут, а для дополнительной мотивации джеты подарят 20 случайным респондентам 100$ Amazon Gift Card!
Пройти можно тут.
Jetbrains
Python Developers Survey 2022
The official Python Developers Survey 2022. Join and contribute to the community knowledge!
Обнаружил у одного Python core developer репозиторий с названием python-horror-show.
В репозитории куча взрывающих мозг примеров с объяснением, почему что-то работает именно так как показано. Один из забавных примеров называется "Enter the void":
#ссылочки
В репозитории куча взрывающих мозг примеров с объяснением, почему что-то работает именно так как показано. Один из забавных примеров называется "Enter the void":
>>> all([])
True
>>> all([[]])
False
>>> all([[[]]])
True
#ссылочки
GitHub
GitHub - pablogsal/python-horror-show: Strange and odd python snippets explained
Strange and odd python snippets explained. Contribute to pablogsal/python-horror-show development by creating an account on GitHub.
Forwarded from Диджитализируй!
Большое интервью Гвидо ван Россума час назад вышло у Лекса Фридмана
https://www.youtube.com/watch?v=-DVyjdw4t9I
0:00 - Introduction
0:48 - CPython
6:01 - Code readability
10:22 - Indentation
26:58 - Bugs
38:26 - Programming fads
53:37 - Speed of Python 3.11
1:18:31 - Type hinting
1:23:49 - mypy
1:29:05 - TypeScript vs JavaScript
1:45:05 - Best IDE for Python
1:55:05 - Parallelism
2:12:58 - Global Interpreter Lock (GIL)
2:22:36 - Python 4.0
2:34:53 - Machine learning
2:44:35 - Benevolent Dictator for Life (BDFL)
2:56:11 - Advice for beginners
3:02:43 - GitHub Copilot
3:06:10 - Future of Python
#IT #Python
https://www.youtube.com/watch?v=-DVyjdw4t9I
0:00 - Introduction
0:48 - CPython
6:01 - Code readability
10:22 - Indentation
26:58 - Bugs
38:26 - Programming fads
53:37 - Speed of Python 3.11
1:18:31 - Type hinting
1:23:49 - mypy
1:29:05 - TypeScript vs JavaScript
1:45:05 - Best IDE for Python
1:55:05 - Parallelism
2:12:58 - Global Interpreter Lock (GIL)
2:22:36 - Python 4.0
2:34:53 - Machine learning
2:44:35 - Benevolent Dictator for Life (BDFL)
2:56:11 - Advice for beginners
3:02:43 - GitHub Copilot
3:06:10 - Future of Python
#IT #Python
YouTube
Guido van Rossum: Python and the Future of Programming | Lex Fridman Podcast #341
Guido van Rossum is the creator of Python programming language. Please support this podcast by checking out our sponsors:
- GiveDirectly: https://givedirectly.org/lex to get gift matched up to $1000
- Eight Sleep: https://www.eightsleep.com/lex to get special…
- GiveDirectly: https://givedirectly.org/lex to get gift matched up to $1000
- Eight Sleep: https://www.eightsleep.com/lex to get special…
Я всё чаще и чаще замечаю Rust рядом с Python...
Совершенно недавно я нашел вот такой HTTP сервер на Rust для приложений на Python - Granian.
Разработчики ставят перед собой следующие цели:
+ Поддержка HTTP версий 1, 2 и 3
+ Один пакет для всех платформ
+ Сервер должен заменить Gunicorn/Uvicorn
+ Обеспечение большей производительности по сравнению с конкурентами.
Сейчас оно умеет в:
+ ASGI/3 и RSGI
+ HTTP/1 и HTTP/2
+ Вебсокеты над HTTP/1 и HTTP/2
+ Поддержка SSL
К сожалению проект пока что в состоянии разработки, поддерживает Питон 3.7 и выше на Unix-платформах и 3.8 и выше на Windows.
Очень надеюсь что с этого что-то вырастет.
#библиотека
Совершенно недавно я нашел вот такой HTTP сервер на Rust для приложений на Python - Granian.
Разработчики ставят перед собой следующие цели:
+ Поддержка HTTP версий 1, 2 и 3
+ Один пакет для всех платформ
+ Сервер должен заменить Gunicorn/Uvicorn
+ Обеспечение большей производительности по сравнению с конкурентами.
Сейчас оно умеет в:
+ ASGI/3 и RSGI
+ HTTP/1 и HTTP/2
+ Вебсокеты над HTTP/1 и HTTP/2
+ Поддержка SSL
К сожалению проект пока что в состоянии разработки, поддерживает Питон 3.7 и выше на Unix-платформах и 3.8 и выше на Windows.
Очень надеюсь что с этого что-то вырастет.
#библиотека
GitHub
GitHub - emmett-framework/granian: A Rust HTTP server for Python applications
A Rust HTTP server for Python applications. Contribute to emmett-framework/granian development by creating an account on GitHub.
Коробка с питоном
Я всё чаще и чаще замечаю Rust рядом с Python... Совершенно недавно я нашел вот такой HTTP сервер на Rust для приложений на Python - Granian. Разработчики ставят перед собой следующие цели: + Поддержка HTTP версий 1, 2 и 3 + Один пакет для всех платформ…
К слову, эти же чуваки сделали довольно известный в узких кругах фреимворк emmett.
Это фреимворк с кучей полезностей и различными новыми подходами. Вот самое интересное:
1) ORM на pyDAl, которая умеет даже в Монгу и FireBird писать! Ну и миграции, каллбеки (похожи на сигналы в Django) и ещё огромная куча всего, почитайте.
2) Валидаторы, правда не такие красивые как c Pydantic.
3) Система авторизации с гибкой системой групп.
4) Даже различные бекенды для кеша есть!
5) Очень интересная система пайплайнов, чем-то похожая на middleware, но с возможностью делать различные действия в зависимости от состояния пайпа.
6) Не менее интересная система сервисов, которая позволяет отдавать ответ не только в html, а в каком-то json или xml.
7) Система расширений.
8) Ну и CLI.
9) А для тех кому нужен REST есть расширение.
Уверен, что почти каждый читающий не знал о существовании этого фреймворка, а жаль. К счастью или сожалению сейчас господствуют микрофреимворки испытывающие unix-way - делай что-то одно и делай это хорошо.
#библиотека
Это фреимворк с кучей полезностей и различными новыми подходами. Вот самое интересное:
1) ORM на pyDAl, которая умеет даже в Монгу и FireBird писать! Ну и миграции, каллбеки (похожи на сигналы в Django) и ещё огромная куча всего, почитайте.
2) Валидаторы, правда не такие красивые как c Pydantic.
3) Система авторизации с гибкой системой групп.
4) Даже различные бекенды для кеша есть!
5) Очень интересная система пайплайнов, чем-то похожая на middleware, но с возможностью делать различные действия в зависимости от состояния пайпа.
6) Не менее интересная система сервисов, которая позволяет отдавать ответ не только в html, а в каком-то json или xml.
7) Система расширений.
8) Ну и CLI.
9) А для тех кому нужен REST есть расширение.
Уверен, что почти каждый читающий не знал о существовании этого фреймворка, а жаль. К счастью или сожалению сейчас господствуют микрофреимворки испытывающие unix-way - делай что-то одно и делай это хорошо.
#библиотека
GitHub
GitHub - emmett-framework/emmett: The web framework for inventors
The web framework for inventors. Contribute to emmett-framework/emmett development by creating an account on GitHub.
Уже какую неделю подряд на Reddit (да и в англоязычных Python комьюнити) хайпит Flet.
Flet - это фреимворк который позволяет строить интерактивные десктопные/мобильные/веб приложения на различных ЯП (пока что увидел только поддержку Python), в итоге получаем SPA/PWA. Построено это всё на Flutter. Пример кода на скриншоте.
Подход с декларативным построением интерфейса вообще не новый - взгляните на Swift UI или же Jetpack Compose. Вопрос лишь в том, кто это использует?
Мне кажется, что:
1. Скорее всего подойдет для тех, кому нужно быстро накостылять MVP или взять замену tkinter.
2. Кейса, где это потащат в прод я не могу придумать по одной простой причине - множество гвоздей забивать микроскопом неудобно. Лучше взять молоток в виде React и спокойно с ним работать.
Во всяком случае - выглядит прикольно. Есть документация с примерами.
#библиотека
Flet - это фреимворк который позволяет строить интерактивные десктопные/мобильные/веб приложения на различных ЯП (пока что увидел только поддержку Python), в итоге получаем SPA/PWA. Построено это всё на Flutter. Пример кода на скриншоте.
Подход с декларативным построением интерфейса вообще не новый - взгляните на Swift UI или же Jetpack Compose. Вопрос лишь в том, кто это использует?
Мне кажется, что:
1. Скорее всего подойдет для тех, кому нужно быстро накостылять MVP или взять замену tkinter.
2. Кейса, где это потащат в прод я не могу придумать по одной простой причине - множество гвоздей забивать микроскопом неудобно. Лучше взять молоток в виде React и спокойно с ним работать.
Во всяком случае - выглядит прикольно. Есть документация с примерами.
#библиотека
Продолжаем смотреть на питоновские библиотеки! На этот раз снова не обойдется без влияния Rust - сегодня мы будем рассматривать библиотеки которые реализуют типы Result и Option.
В стандартной библиотеке Rust есть такой тип как Option - он позволяет, в случае если что-то пошло не так вернуть None, иначе вернуть само значение. Ещё есть Result, который позволяет вернуть либо значение, либо ошибку, которую далее уже должна обработать вызывающая функция.
Всё это нужно по причине того, что в Rust нет конструкции
Зачем это нужно в Python?А оно там не нужно Есть несколько причин:
1) Вы пишите на Rust
3) Такой подход вам ближе
2) Вы пишите в парадигме функционального программирования.
В остальном, как по мне, это просто не нужно. Множить подходы (особенно к обработке ошибок) - самое неприятное что можно сделать в языке.
Но мы продолжаем. Для реализации этих типов есть несколько питоновских библиотек. Вот они: safetywrap и option. Safetywrap мне показался более полным, поэтому будем рассматривать его.
Задача - написать функцию, которая будет проверять значение на отрицательность. Если оно отрицательное - выводим ошибку. С safetywrap это будет выглядеть следующим образом:
#библиотека
В стандартной библиотеке Rust есть такой тип как Option - он позволяет, в случае если что-то пошло не так вернуть None, иначе вернуть само значение. Ещё есть Result, который позволяет вернуть либо значение, либо ошибку, которую далее уже должна обработать вызывающая функция.
Всё это нужно по причине того, что в Rust нет конструкции
try... except
и господствует ФП, которое позволяет строить мощные функциональные конвейеры для обработки получаемых внутри программы данных.Зачем это нужно в Python?
1) Вы пишите на Rust
3) Такой подход вам ближе
2) Вы пишите в парадигме функционального программирования.
В остальном, как по мне, это просто не нужно. Множить подходы (особенно к обработке ошибок) - самое неприятное что можно сделать в языке.
Но мы продолжаем. Для реализации этих типов есть несколько питоновских библиотек. Вот они: safetywrap и option. Safetywrap мне показался более полным, поэтому будем рассматривать его.
Задача - написать функцию, которая будет проверять значение на отрицательность. Если оно отрицательное - выводим ошибку. С safetywrap это будет выглядеть следующим образом:
def check_value_not_negative(val: int) -> Result[int, str]:Как использовать эту функцию? Можно просто её вызвать и в зависимости от результата мы получим либо тип Ok, либо тип Err.
if val >= 0:
return Ok(val)
return Err(f"{val} is negative!")
print(check_value_not_negative(1)) # Ok(1)Но самый сок - это то, что Result содержит в себе кучу полезных функций. Например, в случае получения ошибки мы можем вернуть None или любое другое значение:
print(check_value_not_negative(-1)) # Err('-1 is negative!')
print(check_value_not_negative(-1).or_(None)) # NoneИли проверить, равно ли значение единице, и если нет - вывести сообщение об этом:
print(check_value_not_negative(2).and_then(Как видно, эти типы позволяют писать код, который будет эффективно обрабатывать ошибки, не прибегая к куче
lambda result: Result.ok_if(lambda x: x == 1, result).map_err(
lambda _: "Не равно единице"
)
)) # Err('Не равно единице')
if
и try...except...
Мне нравится такой подход, а вам?#библиотека
FastAPI обновился до 0.89.0 и сделал фичу которой давно не хватало - наконец возвращаемый тип можно писать в аннотациях. Раньше, чтобы OpenAPI дока по нему сгенерировалась, надо было делать так:
Кому интересны детали - вот PR.
#fastapi
@app.get("/", response_model=Model)Теперь же можем делать вот так:
def endpoint():
return Model(name="Yurii")
@app.get("/")Мне до сих пор не понятно, почему так не сделали раньше. Возможно автору такой метод виделся удобным.
def endpoint() -> Model:
return Model(name="Yurii")
Кому интересны детали - вот PR.
#fastapi
GitHub
✨ Add support for function return type annotations to declare the `response_model` by uriyyo · Pull Request #1436 · tiangolo/fastapi
I love the idea of OpenAPI auto-generated schema and the FastAPI at all 😄
This is a feature request.
When I was working with FastAPI I thought that it will be a great idea to use function return ty...
This is a feature request.
When I was working with FastAPI I thought that it will be a great idea to use function return ty...
Разговоры шли давно, но 9ого числа представили PEP 703, который предлагает сделать GIL опциональным. Прототип опубликован в репозитории nogil.
В качестве основания используется то, что Python используют для ML, а GIL - это серьезное препятствие для параллельных вычислений.
В этом PEP так же привели работу с PEP 684, который предлагает прекратить использовать GIL между несколькими интерпретаторами в процессе.
Как думаете, могут ли действительно убрать/сделать опциональным GIL?
#pep
В качестве основания используется то, что Python используют для ML, а GIL - это серьезное препятствие для параллельных вычислений.
В этом PEP так же привели работу с PEP 684, который предлагает прекратить использовать GIL между несколькими интерпретаторами в процессе.
Как думаете, могут ли действительно убрать/сделать опциональным GIL?
#pep
Python Enhancement Proposals (PEPs)
PEP 703 – Making the Global Interpreter Lock Optional in CPython | peps.python.org
CPython’s global interpreter lock (“GIL”) prevents multiple threads from executing Python code at the same time. The GIL is an obstacle to using multi-core CPUs from Python efficiently. This PEP proposes adding a build configuration (--disable-gil) to...
Forwarded from Питонические атаки
В Python 3.12 планируют переделать f-строки в рамках PEP 701 – Syntactic formalization of f-strings.
Дело в том, что f-строки в язык занесли в версии 3.6, когда балом правил еще старый LL(1) парсер, который было сложно расширять, поэтому для f-строк был написан отдельный маленький парсер. Из-за этого они получились слегка неполноценными, а еще в этом отдельном парсере, само собой, были отдельные новые баги. Самое яркое ограничение — это то, что внутри f-строк нельзя использовать те же кавычки, в которых лежит сама строка. Это ж капец как неудобно, что приходится другие кавычки использовать, чтобы просто достать что-то из словаря. У меня линтер на это ругается, и приходится ему каждый раз объяснять, что тут красиво никак не сделать.
Вот, в 3.12 разбор f-строк доверят основному PEG-парсеру, а сам синтаксис f-строк станет частью грамматики языка. Можно будет использовать любые кавычки, которые нравятся. А еще бесконечно вложенные f-строки. Не знаю, зачем нам это, но хорошо, что станет можно. Жду 3.12.
Дело в том, что f-строки в язык занесли в версии 3.6, когда балом правил еще старый LL(1) парсер, который было сложно расширять, поэтому для f-строк был написан отдельный маленький парсер. Из-за этого они получились слегка неполноценными, а еще в этом отдельном парсере, само собой, были отдельные новые баги. Самое яркое ограничение — это то, что внутри f-строк нельзя использовать те же кавычки, в которых лежит сама строка. Это ж капец как неудобно, что приходится другие кавычки использовать, чтобы просто достать что-то из словаря. У меня линтер на это ругается, и приходится ему каждый раз объяснять, что тут красиво никак не сделать.
Вот, в 3.12 разбор f-строк доверят основному PEG-парсеру, а сам синтаксис f-строк станет частью грамматики языка. Можно будет использовать любые кавычки, которые нравятся. А еще бесконечно вложенные f-строки. Не знаю, зачем нам это, но хорошо, что станет можно. Жду 3.12.
Python Enhancement Proposals (PEPs)
PEP 701 – Syntactic formalization of f-strings | peps.python.org
This document proposes to lift some of the restrictions originally formulated in PEP 498 and to provide a formalized grammar for f-strings that can be integrated into the parser directly. The proposed syntactic formalization of f-strings will have some ...
Когда-то давно, когда я только изучал Django, мне хотелось избавиться от бойлерплейта в темплейтах и вынести некоторые части шаблонов (например кнопки) в какие-то отдельные сущности которые можно переиспользовать - например в виде компонентов.
К счастью, в Django есть решение для этого и оно называется template tags. Но у него есть несколько проблем:
1) Необходимо пробрасывать руками js и css зависимости для конкретного тега там, где он используется.
2) Теги плохо кастомизируются, например нет возможности изменить поведение тега, обязательно нужно его переписывать.
Решением этих вопросов занимается пакет с названием django-components. Он предоставляет возможность делать простые, но в то же время мощные переиспользуемые компоненты. А как он справляется с проблемами выше?
1) При объявлении компонента будут грузиться только те js и css, которые указаны в классе компонента. Класс компонента выглядит как-то так:
2) Для изменения поведения компонента можно использовать слоты - это что-то вроде django-блоков внутри компонента. Например, мы можем сделать блок
#django #библиотека
К счастью, в Django есть решение для этого и оно называется template tags. Но у него есть несколько проблем:
1) Необходимо пробрасывать руками js и css зависимости для конкретного тега там, где он используется.
2) Теги плохо кастомизируются, например нет возможности изменить поведение тега, обязательно нужно его переписывать.
Решением этих вопросов занимается пакет с названием django-components. Он предоставляет возможность делать простые, но в то же время мощные переиспользуемые компоненты. А как он справляется с проблемами выше?
1) При объявлении компонента будут грузиться только те js и css, которые указаны в классе компонента. Класс компонента выглядит как-то так:
from django_components import componentСам js/css рендерится только там, где указаны теги
@component.register("calendar")
class Calendar(component.Component):
template_name = "calendar/calendar.html"
def get_context_data(self, date):
return {
"date": date,
}
class Media:
css = "calendar/calendar.css"
js = "calendar/calendar.js"
component_js_dependencies
и component_css_dependencies
.2) Для изменения поведения компонента можно использовать слоты - это что-то вроде django-блоков внутри компонента. Например, мы можем сделать блок
body
внутри компонента и изменять его вид тогда, когда нам нужно:<div class="calendar-component">А теперь импортируем компонент и меняем его body:
<div class="header">
{% slot "header" %}Заголовок календаря{% endslot %}
</div>
<div class="body">
{% slot "body" %}Сегодня <span>{{ date }}</span>{% endslot %}
</div>
</div>
{% component_block "calendar" date="2020-06-06" %}Github | PyPi
{% slot "body" %}А сегодня точно <span>{{ date }}</span>?{% endslot %}
{% endcomponent_block %}
#django #библиотека
Если вы хоть раз задумывались о том, можно ли фичи FastAPI (автогенерация OpenAPI, интеграция с Pydantic, поддержка асинхронности и т.д.) добавить в Django, то я пришел вас обрадовать - есть такой проект под названием django-ninja.
Из приятных фич, которые можно встретить здесь:
1) Версионирование и возможность создания нескольких API инстансов со своей авторизацией и т.д.
2) Класс схемы интегрирован с модельками Django, поэтому можно писать что-то вроде такого:
4) Пагинация! При чем в документации показано, как можно сделать собственный кастомный класс для неё.
5) Поддержка кастомных рендереров ответов, что позволяет перевести сериализацию на ORJSON или отдавать ответы в XML, например.
6) Работа с аутентификацией из под коробки.
7) Ну и асинхронность, тем более разработчики Django работают над ней.
А в остальном он очень похож на FastAPI, особенно когда речь идет о работе с аргументами, схемами и OpenAPI.
Как по мне, выглядит как достойная замена DRF, при чем довольно простая. И об этом я говорю не просто так - в последнее время я делал проекты на FastAPI и возвращаться на Django и тем более DRF было очень непривычно.
Github | Документация
#django #библиотека
Из приятных фич, которые можно встретить здесь:
1) Версионирование и возможность создания нескольких API инстансов со своей авторизацией и т.д.
2) Класс схемы интегрирован с модельками Django, поэтому можно писать что-то вроде такого:
@api.get("/tasks", response=List[TaskSchema])3) Можно делать схемы из моделей, прям как в DRF.
def tasks(request):
return Task.objects.all()
4) Пагинация! При чем в документации показано, как можно сделать собственный кастомный класс для неё.
5) Поддержка кастомных рендереров ответов, что позволяет перевести сериализацию на ORJSON или отдавать ответы в XML, например.
6) Работа с аутентификацией из под коробки.
7) Ну и асинхронность, тем более разработчики Django работают над ней.
А в остальном он очень похож на FastAPI, особенно когда речь идет о работе с аргументами, схемами и OpenAPI.
Как по мне, выглядит как достойная замена DRF, при чем довольно простая. И об этом я говорю не просто так - в последнее время я делал проекты на FastAPI и возвращаться на Django и тем более DRF было очень непривычно.
Github | Документация
#django #библиотека
django-ninja.dev
Django Ninja
Django Ninja - Django REST framework with high performance, easy to learn, fast to code.
Немного про роутинг в FastAPI
Если вы пользовались FastAPI, то наверняка знаете, что роут можно сделать либо асинхронным, либо синхронным. Так когда какой надо делать?
Скорее всего первая мысль которая придет вам в голову будет звучать как-то так - если у нас есть I/O-bound задачи (например работа с БД), то надо использовать асинхронщину, если всё остальное - потоки, процессы и так далее. Но тут есть несколько нюансов:
1) Под капотом FastAPI отлично справляется с обработкой как синхронных, так и асинхронных роутов. Если роут асинхронный, то задача по его обработке запустится в
2) Так как синхронные роуты запускаются в
Возьмем вот такой роут:
А теперь возьмем вот такой роут:
Поэтому, если вам нужно написать на FastAPI небольшой CRUD и вы думаете тащить асинхронную ORM - задумайтесь, а надо ли она вам там вообще?
Ссылки:
- Path operation functions
#fastapi
Если вы пользовались FastAPI, то наверняка знаете, что роут можно сделать либо асинхронным, либо синхронным. Так когда какой надо делать?
Скорее всего первая мысль которая придет вам в голову будет звучать как-то так - если у нас есть I/O-bound задачи (например работа с БД), то надо использовать асинхронщину, если всё остальное - потоки, процессы и так далее. Но тут есть несколько нюансов:
1) Под капотом FastAPI отлично справляется с обработкой как синхронных, так и асинхронных роутов. Если роут асинхронный, то задача по его обработке запустится в
event loop
, если синхронный - то в thread pool
.2) Так как синхронные роуты запускаются в
thread pool
, иногда просто нет вообще никакого смысла тащить в проект асинхронную ORM, так как всё и так будет работать не блокируя основное приложение.Возьмем вот такой роут:
@router.get("/nonblocking-sync-operation")После того как мы перейдем по этому роуту, мы будем ждать 10 секунд и в конце получим ответ. При этом сам FastAPI не заблокируется, и сможет обрабатывать другие подключения - потому что функция запустилась в отдельном потоке.
def nonblocking_sync_operation():
time.sleep(10)
return {"test": "test"}
А теперь возьмем вот такой роут:
@router.get("/blocking-sync-operation")Здесь после перехода по роуту функция запустится в event loop и sleep заблокирует всё приложение до тех пор, пока он не пройдет. То есть, FastAPI вообще перестанет принимать подключения до тех пор, пока функция не выполнится.
async def blocking_sync_operation():
time.sleep(10)
return {"test": "test"}
Поэтому, если вам нужно написать на FastAPI небольшой CRUD и вы думаете тащить асинхронную ORM - задумайтесь, а надо ли она вам там вообще?
Ссылки:
- Path operation functions
#fastapi
В PEP 695 предлагают наконец переделать синтаксис для указания дженериков и ввести новый оператор для указания алиасов.
1) Что там с дженериками?
Например, если раньше было так:
Раньше алиасы типов записывались вот так:
#pep
1) Что там с дженериками?
Например, если раньше было так:
_T_co = TypeVar("_T_co", covariant=True, bound=str)То сейчас предлагают сделать так:
class ClassA(Generic[_T_co]):
def method1(self) -> _T_co:
...
class ClassA[T: str]:2) А что с алиасами?
def method1(self) -> T:
...
Раньше алиасы типов записывались вот так:
_T = TypeVar("_T")Сейчас предлагают сделать вот так:
ListOrSet: TypeAlias = list[_T] | set[_T]
type ListOrSet[T] = list[T] | set[T]Если не ошибаюсь, то ждем в 3.12, PEP уже приняли.
#pep
Python Enhancement Proposals (PEPs)
PEP 695 – Type Parameter Syntax | peps.python.org
This PEP specifies an improved syntax for specifying type parameters within a generic class, function, or type alias. It also introduces a new statement for declaring type aliases.
Очень годный доклад о том как начинать проекты на Django.
Рассмотрели нужность батареек, как правильно писать логику и что там на самом деле с админкой и DRF.
#django #посмотреть
Рассмотрели нужность батареек, как правильно писать логику и что там на самом деле с админкой и DRF.
#django #посмотреть
YouTube
Как и зачем начинать проекты на Django в 2021 году / Фёдор Борщёв
Приглашаем на Moscow Python Conf 2023, которая пройдет 19 и 20 мая 2023 в Москве в рамках Positive Hack Days.
Программа, подробности и билеты по ссылке https://conf.python.ru/moscow/2023
--------
Moscow Python Conf++ 2021
Профессиональная конференция для…
Программа, подробности и билеты по ссылке https://conf.python.ru/moscow/2023
--------
Moscow Python Conf++ 2021
Профессиональная конференция для…
Один из моих любимых докладов о том, почему вам не нужен асинхронный ORM.
В докладе автор рассказывает про то, что происходит под капотом у асинхронной алхимии, поэтому рекомендуется к просмотру тем, кто пишет бекенд.
#sqlalchemy #посмотреть
В докладе автор рассказывает про то, что происходит под капотом у асинхронной алхимии, поэтому рекомендуется к просмотру тем, кто пишет бекенд.
#sqlalchemy #посмотреть
YouTube
Почему вам не нужен асинхронный ORM / Денис Катаев
Приглашаем на Moscow Python Conf 2023, которая пройдет 19 и 20 мая 2023 в Москве в рамках Positive Hack Days.
Программа, подробности и билеты по ссылке https://conf.python.ru/moscow/2023
--------
Moscow Python Conf++ 2021
Профессиональная конференция для…
Программа, подробности и билеты по ссылке https://conf.python.ru/moscow/2023
--------
Moscow Python Conf++ 2021
Профессиональная конференция для…