aiogram-dialog от @Tishka17 — это фреймворк для разработки интерактивных сообщений и меню в вашем телеграмм-боте, подобно обычному приложению с графическим интерфейсом.
Позволяет избавиться от копипасты и сделать код более структурированным:
* разделение извлечения данных, рендеринга и обработки действий. Вам ничего не нужно делать для повторного отображения одного и того же контента после разных действий, переходы между состояниями отделены от логики отображения.
* многоразовые виджеты. Вы можете создать календарь или выбор из нескольких вариантов в любой точке вашего приложения без копирования и вставки его внутренней логики
* ограниченный контекст. Любой диалог хранит данные до его закрытия, несколько открытых диалогов обрабатывают свои данные независимо
Лицензия: Apache-2.0
Репозиторий: https://github.com/Tishka17/aiogram_dialog/
Pypi:
Позволяет избавиться от копипасты и сделать код более структурированным:
* разделение извлечения данных, рендеринга и обработки действий. Вам ничего не нужно делать для повторного отображения одного и того же контента после разных действий, переходы между состояниями отделены от логики отображения.
* многоразовые виджеты. Вы можете создать календарь или выбор из нескольких вариантов в любой точке вашего приложения без копирования и вставки его внутренней логики
* ограниченный контекст. Любой диалог хранит данные до его закрытия, несколько открытых диалогов обрабатывают свои данные независимо
Лицензия: Apache-2.0
Репозиторий: https://github.com/Tishka17/aiogram_dialog/
Pypi:
pip install aiogram_dialog
Обсуждение проекта - @aiogram_dialog❤🔥10👍5🤔2💩2🔥1🕊1
PyHeap от @ivanyu - утилита для дампинга и анализа кучи (heap) CPython-процессов.
Использует GDB для подключения к целевому процессу. Имеет графический браузерный UI для визуализации и исследования дампов. Поддерживает Docker (и вообще Linux namespaces).
По общей идее утилита похожа на связку jmap + Eclipse Memory Analyzer из мира Java.
Лицензия: Apache License 2.0
Репозиторий: https://github.com/ivanyu/pyheap
Использует GDB для подключения к целевому процессу. Имеет графический браузерный UI для визуализации и исследования дампов. Поддерживает Docker (и вообще Linux namespaces).
По общей идее утилита похожа на связку jmap + Eclipse Memory Analyzer из мира Java.
Лицензия: Apache License 2.0
Репозиторий: https://github.com/ivanyu/pyheap
🔥4👍2
adaptix от @Tishka17 и @pvlzhr — это библиотека для сериализации и десериализации объектов, которая гибко подстраивается под ваши нужды.
Основные преимущества:
1. Высокая производительность — до двух раз быстрее, чем pydantic v2 (бенчмарки)
2. Группировка настроек конвертации, позволяющая следовать принципу DRY.
3. Различные правила сериализации и десериализации для одних и тех же моделей.
4. Работа с любыми моделями (dataclass, NamedTuple, TypedDict, attrs) без необходимости менять что-либо в самих классах.
◾️ Репозиторий
◾️ Документация
◾️ Группа
Основные преимущества:
1. Высокая производительность — до двух раз быстрее, чем pydantic v2 (бенчмарки)
2. Группировка настроек конвертации, позволяющая следовать принципу DRY.
3. Различные правила сериализации и десериализации для одних и тех же моделей.
4. Работа с любыми моделями (dataclass, NamedTuple, TypedDict, attrs) без необходимости менять что-либо в самих классах.
◾️ Репозиторий
◾️ Документация
◾️ Группа
👍4🔥3❤🔥1
GitHub
GitHub - Codwizer/mhjson: mhjson is a simple, elegant Python package to Query over any type of JSON Data. It'll make your life…
mhjson is a simple, elegant Python package to Query over any type of JSON Data. It'll make your life easier by giving the flavour of an ORM-like query on your JSON. - Codwizer/mhjson
mhjson от @dev_kitten — это простой и элегантный Python-пакет для запросов к любым типам JSON-данных.
Он облегчит вам жизнь, предоставив вкус ORM-подобных запросов к вашему JSON.
Он облегчит вам жизнь, предоставив вкус ORM-подобных запросов к вашему JSON.
❤🔥6❤2👎1🥰1🤔1
Dishka от @Tishka17 — это удобный и мощный IoC-контейнер.
Если вы следуете принципу Dependency Injection, то благодаря этой библиотеке удобнее управлять созданием и жизнью различных объектов
Основные возможности:
1. Не привязан к другим фреймворкам
2. Поддерживает финализацию зависимостей и asyncio
3. Зависимости кэшируются, поэтому один и тот же объект может быть переиспользован пока он жив.
4. Зависимости имеют ограниченное время жизни (скоуп) и вы сами управляете им
5. Фабрики зависимостей можно группировать в классы и компоненты, что позволяет делать контейнер модульным
6. Можно декорировать объекты, использовать один объект для нескольких типов
7. При старте проверяется корректность конфигурации контейнера, что позволяет исключить многие ошибки
💻 Репозиторий
📚 Документация
🚀 Группа
Если вы следуете принципу Dependency Injection, то благодаря этой библиотеке удобнее управлять созданием и жизнью различных объектов
Основные возможности:
1. Не привязан к другим фреймворкам
2. Поддерживает финализацию зависимостей и asyncio
3. Зависимости кэшируются, поэтому один и тот же объект может быть переиспользован пока он жив.
4. Зависимости имеют ограниченное время жизни (скоуп) и вы сами управляете им
5. Фабрики зависимостей можно группировать в классы и компоненты, что позволяет делать контейнер модульным
6. Можно декорировать объекты, использовать один объект для нескольких типов
7. При старте проверяется корректность конфигурации контейнера, что позволяет исключить многие ошибки
📚 Документация
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16👍2❤1👎1
FastStream от @diementros и компании Airt - современный фреймворк для разработки асинхронных сервисов.
Если вы работаете с RabbitMQ/Kafka/NATS/[другой брокер] - вам определенно стоит взглянуть на FastStream. Его основные преимущества:
1) Простой и интуитивный API. Описывайте бизнес-логику, а не инфраструктуру
2) In-memory эмуляция брокеров. Тестируйте ваши сервисы без внешних зависимостей в CI
3) Готовая AsyncAPI документация, автоматически сгенерированная прямо из кода проекта
4) Отличная интеграция с телеметрией: удобное логирование, нативная поддержка OpenTelemetry
5) Сериализация входящих сообщений через Pydantic на основе аннотаций типов
6) Собственная минималистичная DI система (для эстетов есть интеграция с dishka)
Также проект отчаяно нуждается в контрибуторах и амбасадорах. Если вы ищете интересный проект для участия в Open Source - это ваш шанс получить галочку в портфолио и сделать мир чуточку лучше. PR Review, участие в discussions, большие и маленькие фичи, правки в документацию - мы будем рады любому участию!
Также в telegram группе мы часто обсуждаем планируемые фичи, так что это ваш шанс напрямую повлиять на развитие проекта.
📱 Репозиторий проекта
📚 Документация
📱 RU Telegram
📱 EN Discord
Если вы работаете с RabbitMQ/Kafka/NATS/[другой брокер] - вам определенно стоит взглянуть на FastStream. Его основные преимущества:
1) Простой и интуитивный API. Описывайте бизнес-логику, а не инфраструктуру
2) In-memory эмуляция брокеров. Тестируйте ваши сервисы без внешних зависимостей в CI
3) Готовая AsyncAPI документация, автоматически сгенерированная прямо из кода проекта
4) Отличная интеграция с телеметрией: удобное логирование, нативная поддержка OpenTelemetry
5) Сериализация входящих сообщений через Pydantic на основе аннотаций типов
6) Собственная минималистичная DI система (для эстетов есть интеграция с dishka)
Также проект отчаяно нуждается в контрибуторах и амбасадорах. Если вы ищете интересный проект для участия в Open Source - это ваш шанс получить галочку в портфолио и сделать мир чуточку лучше. PR Review, участие в discussions, большие и маленькие фичи, правки в документацию - мы будем рады любому участию!
Также в telegram группе мы часто обсуждаем планируемые фичи, так что это ваш шанс напрямую повлиять на развитие проекта.
📚 Документация
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11❤1🥰1
По следам вопроса в чате: как не ошибиться с окружением при установке пакета
Если вы работаете с Python, у вас на машине наверняка больше одного окружения, используй вы virtualenv, pyenv, pipenv, poetry или что-то ещё. По разным причинам бинарник python и других инструментов (`pip`,
Многие проблемы решаются, если вообще отказаться от запуска команд помимо
Так у нас гарантированно вызовется
Если же это не помогло, вот несколько рецептов для дебага, что же происходит при установке.
Как посмотреть, куда указывает
Как посмотреть, с каким
Как посмотреть, куда
—————
Мы расширяем тематику канала и ищем авторов. Если вы хотите поделиться библиотекой, новостью или просто хорошим техническим материалом, пишите @saluev или любому другому из админов!
Если вы работаете с Python, у вас на машине наверняка больше одного окружения, используй вы virtualenv, pyenv, pipenv, poetry или что-то ещё. По разным причинам бинарник python и других инструментов (`pip`,
black, ...) могут разъехаться и начать указывать на разные окружения, что приводит к ошибкам вида "No module named X", хотя вы только что установили X.Многие проблемы решаются, если вообще отказаться от запуска команд помимо
python. Почти все пакеты можно запустить через python -m:
$ python -m pip install numpy
...
Так у нас гарантированно вызовется
pip из той же инсталляции, что и python.Если же это не помогло, вот несколько рецептов для дебага, что же происходит при установке.
Как посмотреть, куда указывает
python:
$ which python
/Users/saluev/myproject/.venv/bin/python
Как посмотреть, где python ищет пакеты:
$ python -c "import sys, pprint; pprint.pprint(sys.path)"
['',
'/opt/homebrew/Cellar/python@3.12/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python312.zip',
'/opt/homebrew/Cellar/python@3.12/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12',
'/opt/homebrew/Cellar/python@3.12/3.12.7_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/lib-dynload',
'/Users/saluev/myproject/.venv/lib/python3.12/site-packages']
Как посмотреть, с каким
python работает pip:
$ pip debug
pip version: pip 24.2 from /Users/saluev/myproject/.venv/lib/python3.12/site-packages/pip (python 3.12)
sys.version: 3.12.7 (main, Oct 1 2024, 02:05:46) [Clang 16.0.0 (clang-1600.0.26.3)]
sys.executable: /Users/saluev/myproject/.venv/bin/python3.12
...
Как посмотреть, куда
pip установил ваш пакет:
$ pip show numpy
...
...
...
Location: /Users/saluev/myproject/.venv/lib/python3.12/site-packages
...
—————
Мы расширяем тематику канала и ищем авторов. Если вы хотите поделиться библиотекой, новостью или просто хорошим техническим материалом, пишите @saluev или любому другому из админов!
❤🔥8🔥1
По следам вопроса в чате: как раздавать контент (картинки, документы, JS), и как это делать приватно
В большинстве популярных веб-фреймворков для Python есть опция раздачи статических файлов. И всегда в документации указано, что эта функциональность — для разработки и отладки, но не для продакшн-решения. А как выглядит продакшн-решение?
Простой уровень — настроить для этого веб-сервер (nginx, traefik, ...). Он будет раздавать статику быстрее, чем веб-фреймворк на Python, не будет тормозить API-запросы и позаботится о многих нюансах (сжатии, HTTP-хедерах для кэширования, рейтлимитах и проч.). Это годится для раздачи статики — JS или картинок, входящих в дизайн сайта.
Следующий уровень начинается, когда нагрузка на сервер большая, распределённая географически, и/или когда у нас появляется UGC (user-generated content), т.е. пользователи сами начинают заливать нам картинки, PDF-документы и прочие файлы в приличном объёме. В таком случае используют CDN (content delivery network) — Amazon S3, его аналоги (есть практически во всех облаках) и продвинутые обёртки для высокой нагрузки. CDN занимается за нас кэшированием (продвинутые сервисы даже могут раскопировать файлы по датацентрам в нескольких регионах для более быстрой раздачи), горизонтальным масштабированием, отказоустойчивостью и так далее.
При этом использование CDN, как правило, крайне дёшево (ставка порядка $0.02/GB в месяц означает, что даже когда ваши пользователи зальют терабайт данных, это будет обходиться всего в $20 в месяц) и очень просто — все облака предоставляют унифицированное S3-подобное API и, соответственно, могут быть подключены посредством одной библиотеки boto3).
Следующий вопрос — что делать, если контент приватный, например, паспорта, контракты и прочие документы, и не должен попадать в руки неавторизованных пользователей. Тут возникает два больших риска:
— ссылка на документ утечёт в интернет (например, её проиндексирует поисковик) и злоумышленник извне сможет получить доступ к документу;
— пользователь с доступом к одному документу займётся обходом адресов и получит несанкционированный доступ к другим документам.
Для решения первой проблемы S3 предоставляет возможность создавать временные подписанные ссылки. То есть мы делаем все файлы в хранилище по умолчанию недоступными никому и на стороне бэкенда выдаём временные ссылки с коротким сроком жизни, чтобы авторизованные пользователи могли скачивать файлы.
Вторая проблема при этом перестаёт быть актуальной, но чтобы перестраховаться на случай случайного изменения настроек приватности, общая рекомендация — использовать UUID (или ObjectId или другие строковые идентификаторы) вместо номеров для приватных файлов. Эта полумера также может быть использована без временных ссылок для не-очень-но-немного-приватного контента; например, в соцсетях фотография может быть защищена настройками приватности, но по прямой ссылке картинка всегда доступна — потому что генерировать приватную ссылку для каждой картинки в зависимости от пользовательских настроек приватности было бы слишком накладно; при этом перебирать адреса и смотреть чужие приватные фото практически невозможно.
—————
Мы расширяем тематику канала и ищем авторов. Если вы хотите поделиться библиотекой, новостью или просто хорошим техническим материалом, пишите @saluev или любому другому из админов!
В большинстве популярных веб-фреймворков для Python есть опция раздачи статических файлов. И всегда в документации указано, что эта функциональность — для разработки и отладки, но не для продакшн-решения. А как выглядит продакшн-решение?
Простой уровень — настроить для этого веб-сервер (nginx, traefik, ...). Он будет раздавать статику быстрее, чем веб-фреймворк на Python, не будет тормозить API-запросы и позаботится о многих нюансах (сжатии, HTTP-хедерах для кэширования, рейтлимитах и проч.). Это годится для раздачи статики — JS или картинок, входящих в дизайн сайта.
Следующий уровень начинается, когда нагрузка на сервер большая, распределённая географически, и/или когда у нас появляется UGC (user-generated content), т.е. пользователи сами начинают заливать нам картинки, PDF-документы и прочие файлы в приличном объёме. В таком случае используют CDN (content delivery network) — Amazon S3, его аналоги (есть практически во всех облаках) и продвинутые обёртки для высокой нагрузки. CDN занимается за нас кэшированием (продвинутые сервисы даже могут раскопировать файлы по датацентрам в нескольких регионах для более быстрой раздачи), горизонтальным масштабированием, отказоустойчивостью и так далее.
При этом использование CDN, как правило, крайне дёшево (ставка порядка $0.02/GB в месяц означает, что даже когда ваши пользователи зальют терабайт данных, это будет обходиться всего в $20 в месяц) и очень просто — все облака предоставляют унифицированное S3-подобное API и, соответственно, могут быть подключены посредством одной библиотеки boto3).
Следующий вопрос — что делать, если контент приватный, например, паспорта, контракты и прочие документы, и не должен попадать в руки неавторизованных пользователей. Тут возникает два больших риска:
— ссылка на документ утечёт в интернет (например, её проиндексирует поисковик) и злоумышленник извне сможет получить доступ к документу;
— пользователь с доступом к одному документу займётся обходом адресов и получит несанкционированный доступ к другим документам.
Для решения первой проблемы S3 предоставляет возможность создавать временные подписанные ссылки. То есть мы делаем все файлы в хранилище по умолчанию недоступными никому и на стороне бэкенда выдаём временные ссылки с коротким сроком жизни, чтобы авторизованные пользователи могли скачивать файлы.
Вторая проблема при этом перестаёт быть актуальной, но чтобы перестраховаться на случай случайного изменения настроек приватности, общая рекомендация — использовать UUID (или ObjectId или другие строковые идентификаторы) вместо номеров для приватных файлов. Эта полумера также может быть использована без временных ссылок для не-очень-но-немного-приватного контента; например, в соцсетях фотография может быть защищена настройками приватности, но по прямой ссылке картинка всегда доступна — потому что генерировать приватную ссылку для каждой картинки в зависимости от пользовательских настроек приватности было бы слишком накладно; при этом перебирать адреса и смотреть чужие приватные фото практически невозможно.
—————
Мы расширяем тематику канала и ищем авторов. Если вы хотите поделиться библиотекой, новостью или просто хорошим техническим материалом, пишите @saluev или любому другому из админов!
Amazon
Sharing objects with presigned URLs - Amazon Simple Storage Service
Describes how to set up your objects so that you can share them with others by creating a presigned URL to download the objects.
👍8❤🔥1🤗1😎1
По следам обсуждения в чате: сравнение перфоманса фреймворков
Всякий раз, когда релизится Новый Самый Быстрый Веб-Фреймворк на Python, релиз сопровождается красивыми картинками, на которых миллион RPS (requests per second, запросов в секунду) нового фреймворка сравнивается с полумиллионом RPS предыдущего Самого Быстрого фреймворка. После чего можно часто услышать тезис «X вдвое быстрее Y» при обсуждении технических решений.
Вдвое большее RPS в бенчмарке, конечно, не означает ни что проект будет отвечать в два раза быстрее, ни что проект будет держать вдвое бо́льшую нагрузку. По ряду причин, и в первую очередь из-за закона Амдала.
Закон Амдала изначально был сформулирован, чтобы оценить, насколько увеличение числа параллельных процессоров может ускорить программу, но может использоваться и для анализа ускорения за счёт любых других способов ускорить отдельные части. Закон формулируется так. Если мы используем какой-то способ ускорить программу (в нашем случае — замену веб-фреймворка), то у нас есть процент X времени работы программы, приходящийся на ускоряемый код (в нашем случае — на обработку запроса фреймворком) и процент Y = 1 - X времени, приходящийся на весь остальной код (в нашем случае — на бизнес-логику, включая походы в базу данных). Если мы ускоряем веб-фреймворк в N раз, то общее ускорение всего проекта получается порядка 1 / (Y + X / N). Например, если мы ускорили веб-фреймворк в два раза, но обработка запроса занимает 5% времени, то суммарное ускорение будет ~2.5%.
На практике время, занимаемое веб-фреймворком, невелико по сравнению с временем, уходящим на бизнес-логику, даже в простых проектах. В бенчмарке ASGI-фреймворков они демонстрируют латенси порядка 5 мс; это сопоставимо с одним запросом в базу данных — в сложном высоконагруженном сервисе их наверняка будет больше.
При принятии решения, на каком фреймворке писать проект, следует учесть не только его показатели в бенчмарках, но и не менее значимые факторы:
• зрелость фреймворка и комьюнити — пройдены ли все грабли, существует ли активное ядро меинтейнеров, исчерпывающа ли документация и насыщен ли знаниями StackOverflow;
• экспертиза — знают ли разработчики в вашей команде этот фреймворк (или хотя бы ближайшие аналоги) достаточно хорошо;
• рыночная востребованность — легко ли нанимать разработчиков с опытом в этом фреймворке и желании писать на нём (и будет ли легко через несколько лет).
─────
Мы расширяем тематику канала и ищем авторов. Если вы хотите поделиться библиотекой, новостью или просто хорошим техническим материалом, пишите @saluev или любому другому из админов!
Всякий раз, когда релизится Новый Самый Быстрый Веб-Фреймворк на Python, релиз сопровождается красивыми картинками, на которых миллион RPS (requests per second, запросов в секунду) нового фреймворка сравнивается с полумиллионом RPS предыдущего Самого Быстрого фреймворка. После чего можно часто услышать тезис «X вдвое быстрее Y» при обсуждении технических решений.
Вдвое большее RPS в бенчмарке, конечно, не означает ни что проект будет отвечать в два раза быстрее, ни что проект будет держать вдвое бо́льшую нагрузку. По ряду причин, и в первую очередь из-за закона Амдала.
Закон Амдала изначально был сформулирован, чтобы оценить, насколько увеличение числа параллельных процессоров может ускорить программу, но может использоваться и для анализа ускорения за счёт любых других способов ускорить отдельные части. Закон формулируется так. Если мы используем какой-то способ ускорить программу (в нашем случае — замену веб-фреймворка), то у нас есть процент X времени работы программы, приходящийся на ускоряемый код (в нашем случае — на обработку запроса фреймворком) и процент Y = 1 - X времени, приходящийся на весь остальной код (в нашем случае — на бизнес-логику, включая походы в базу данных). Если мы ускоряем веб-фреймворк в N раз, то общее ускорение всего проекта получается порядка 1 / (Y + X / N). Например, если мы ускорили веб-фреймворк в два раза, но обработка запроса занимает 5% времени, то суммарное ускорение будет ~2.5%.
На практике время, занимаемое веб-фреймворком, невелико по сравнению с временем, уходящим на бизнес-логику, даже в простых проектах. В бенчмарке ASGI-фреймворков они демонстрируют латенси порядка 5 мс; это сопоставимо с одним запросом в базу данных — в сложном высоконагруженном сервисе их наверняка будет больше.
При принятии решения, на каком фреймворке писать проект, следует учесть не только его показатели в бенчмарках, но и не менее значимые факторы:
• зрелость фреймворка и комьюнити — пройдены ли все грабли, существует ли активное ядро меинтейнеров, исчерпывающа ли документация и насыщен ли знаниями StackOverflow;
• экспертиза — знают ли разработчики в вашей команде этот фреймворк (или хотя бы ближайшие аналоги) достаточно хорошо;
• рыночная востребованность — легко ли нанимать разработчиков с опытом в этом фреймворке и желании писать на нём (и будет ли легко через несколько лет).
─────
Мы расширяем тематику канала и ищем авторов. Если вы хотите поделиться библиотекой, новостью или просто хорошим техническим материалом, пишите @saluev или любому другому из админов!
👍5❤1
Forwarded from Советы разработчикам (python и не только)
Паттерны работы с базами данных
В большинстве проектов мы храним какие-то данные. Для этого используются разные виды баз данных: реляционные, nosql или даже специализированные HTTP API. Такие хранилища имеют специфическое API, которое мы обычно хотим скрыть от основного кода за некоторой абстракцией. Вот стандартные варианты, описанные, в частности, Мартином Фаулером.
Первая группа паттернов работы с БД - отделяющие реализацию операций с хранилищем от данных. Благодаря такому разделению, мы можем построить несколько реализаций шлюза, возвращающих однотипные структуры (например, для заглушек на время тестирования или использования нескольких источников данных). Обратите внимание, что в паттернах этой группы мы можем полностью скрыть детали организации хранилища.
DAO - наиболее простой вариант, он представляет собой достаточно тупой класс, который просто выполняет операции с хранилищем и возвращает данные в том или ином виде. Он не должен содержать какого-то своего состояния (будь то кэши или IdentityMap). Он получает и возвращает только данные в виде неких абстрактных RecordSet или простых DTO, то есть структур, не содержащих логики. Плюсы такого паттерна: простота реализации, возможность точечного тюнинга запросов. Паттерн описан в "Core J2EE Patterns", а у Фаулера встречается очень близкое описание под именем Table Data Gateway.
Data Mapper - в отличие от DAO занимается не просто передачей данных, а двусторонней синхронизацией моделей бизнес логики с хранилищем. То есть он может получать какие-то сущности и потом сохранять их обратно. Внутри он может содержать IdentityMap для исключения дублей модели с одним identity или создания лишних запросов на загрузку. Каждый маппер работает с моделью определенного типа, но в случае составных моделей он иногда может обращаться к другим мапперам (например, при использовании
Repository - фактически вариант Data Mapper, предназначенный для работы с корневыми сущностями. Для прикладной бизнес логики репозиторий выглядит как коллекция, содержащая корни агрегатов. Он может использоваться для получения полиморфных моделей, а также может возвращать некоторую сводно-статистическую информацию (например, количество элементов или сумму полей) или даже выполнять какие-то расчеты, не выходящие за пределы общей компетенции хранилища данных. Это основной паттерн при использовании богатых доменных моделей. Паттерн описан у Эрика Эванса, а у Фаулера встречаются некоторые варианты его реализации.
Вторая группа - паттерны, смешивающие данные и работу с хранилищем. Их использование может усложнить тестирование или изменение кода, но, тем не менее, они используются.
Raw Data Gateway - предлагает каждой строке таблицы поставить в соответствие экземпляр класса. Мы получаем отдельный класс Finder для загрузки строк и собственно класс шлюза строки, который предоставляет доступ к загруженным данным и обладает методами сохранения себя в БД.
Active Record - вариант RDG, но содержащий бизнес логику. По факту, мы имеем богатые доменные модели не абстрагированные от хранилища. Часто методы загрузки данных реализованы просто как static-методы в этом же классе вместо выделения отдельного Finder.
Строит отметить, что многие ORM в Python реализуют Active Record и активно используют при этом неявный контроль соединений и транзакций. В отличие от них SQLAlchemy реализует паттерн Data Mapper и может дать больший уровень абстракции над хранилищем (обратите внимание на подход с
Дополнительные материалы:
• http://www.corej2eepatterns.com/Patterns2ndEd/DataAccessObject.htm
• https://martinfowler.com/eaaCatalog/identityMap.html
• https://docs.sqlalchemy.org/en/20/orm/dataclasses.html#applying-orm-mappings-to-an-existing-dataclass-legacy-dataclass-use
В большинстве проектов мы храним какие-то данные. Для этого используются разные виды баз данных: реляционные, nosql или даже специализированные HTTP API. Такие хранилища имеют специфическое API, которое мы обычно хотим скрыть от основного кода за некоторой абстракцией. Вот стандартные варианты, описанные, в частности, Мартином Фаулером.
Первая группа паттернов работы с БД - отделяющие реализацию операций с хранилищем от данных. Благодаря такому разделению, мы можем построить несколько реализаций шлюза, возвращающих однотипные структуры (например, для заглушек на время тестирования или использования нескольких источников данных). Обратите внимание, что в паттернах этой группы мы можем полностью скрыть детали организации хранилища.
DAO - наиболее простой вариант, он представляет собой достаточно тупой класс, который просто выполняет операции с хранилищем и возвращает данные в том или ином виде. Он не должен содержать какого-то своего состояния (будь то кэши или IdentityMap). Он получает и возвращает только данные в виде неких абстрактных RecordSet или простых DTO, то есть структур, не содержащих логики. Плюсы такого паттерна: простота реализации, возможность точечного тюнинга запросов. Паттерн описан в "Core J2EE Patterns", а у Фаулера встречается очень близкое описание под именем Table Data Gateway.
Data Mapper - в отличие от DAO занимается не просто передачей данных, а двусторонней синхронизацией моделей бизнес логики с хранилищем. То есть он может получать какие-то сущности и потом сохранять их обратно. Внутри он может содержать IdentityMap для исключения дублей модели с одним identity или создания лишних запросов на загрузку. Каждый маппер работает с моделью определенного типа, но в случае составных моделей он иногда может обращаться к другим мапперам (например, при использовании
select-in load). При использовании Unit Of Work, тот обращается именно к мапперу для сохранения данных.Repository - фактически вариант Data Mapper, предназначенный для работы с корневыми сущностями. Для прикладной бизнес логики репозиторий выглядит как коллекция, содержащая корни агрегатов. Он может использоваться для получения полиморфных моделей, а также может возвращать некоторую сводно-статистическую информацию (например, количество элементов или сумму полей) или даже выполнять какие-то расчеты, не выходящие за пределы общей компетенции хранилища данных. Это основной паттерн при использовании богатых доменных моделей. Паттерн описан у Эрика Эванса, а у Фаулера встречаются некоторые варианты его реализации.
Вторая группа - паттерны, смешивающие данные и работу с хранилищем. Их использование может усложнить тестирование или изменение кода, но, тем не менее, они используются.
Raw Data Gateway - предлагает каждой строке таблицы поставить в соответствие экземпляр класса. Мы получаем отдельный класс Finder для загрузки строк и собственно класс шлюза строки, который предоставляет доступ к загруженным данным и обладает методами сохранения себя в БД.
Active Record - вариант RDG, но содержащий бизнес логику. По факту, мы имеем богатые доменные модели не абстрагированные от хранилища. Часто методы загрузки данных реализованы просто как static-методы в этом же классе вместо выделения отдельного Finder.
Строит отметить, что многие ORM в Python реализуют Active Record и активно используют при этом неявный контроль соединений и транзакций. В отличие от них SQLAlchemy реализует паттерн Data Mapper и может дать больший уровень абстракции над хранилищем (обратите внимание на подход с
map_imperatively).Дополнительные материалы:
• http://www.corej2eepatterns.com/Patterns2ndEd/DataAccessObject.htm
• https://martinfowler.com/eaaCatalog/identityMap.html
• https://docs.sqlalchemy.org/en/20/orm/dataclasses.html#applying-orm-mappings-to-an-existing-dataclass-legacy-dataclass-use
🔥4👍1
Статья: как увеличить скорость python-скриптов: C-расширения и Python/C API
Известно, что зачастую, когда перфоманса Python не хватает (то есть почти всегда), можно ускорять отдельные участки кода за счёт переписывания их на C. Так, например, сделан NumPy и многие другие вычислительные пакеты. В свежевышедшей статье-туториале автор детально разбирает, как устроен пакет с C-кодом, как организовать сборку и как выглядит Python C API, с практическими примерами и бенчмарками. Рекомендуется к ознакомлению всем, кто выбрал Python как свой основной язык программирования.
Читать целиком на Хабре: https://habr.com/ru/companies/timeweb/articles/875420/
Известно, что зачастую, когда перфоманса Python не хватает (то есть почти всегда), можно ускорять отдельные участки кода за счёт переписывания их на C. Так, например, сделан NumPy и многие другие вычислительные пакеты. В свежевышедшей статье-туториале автор детально разбирает, как устроен пакет с C-кодом, как организовать сборку и как выглядит Python C API, с практическими примерами и бенчмарками. Рекомендуется к ознакомлению всем, кто выбрал Python как свой основной язык программирования.
Читать целиком на Хабре: https://habr.com/ru/companies/timeweb/articles/875420/
Хабр
Как увеличить скорость python-скриптов: C-расширения и Python/C API
Во время разработки ПО мы сталкиваемся с выбором между удобством языка и его производительностью. Python завоевал популярность благодаря простоте и изящности, но когда дело доходит до низкоуровневых...
❤1👍1
Forwarded from Советы разработчикам (python и не только)
float и Decimal
Вас никогда не удивляло, что
Дело в том, что
Где:
•
•
•
Вот так мы можем примерно представить 0.1 в виде float. Примерно – потому что все вычисления идут с погрешностью. Мы можем проверить данное утверждение, добавив погрешность вручную:
Значение внешне не изменилось при добавлении погрешности. Посмотрим на sys.float_info.epsilon, который устанавливает необходимый порог для минимальных отличий 1.0 от следующего float числа.
Как конкретно будет выглядеть
И вот ответ про 0.1 + 0.2, полное демо с битиками:
Числа не равны друг другу, потому что их разница больше предельной точности float. А сам Decimal может использовать любую точность под задачу.
Но и
Почему всем норм, что у нас с
Разница в 3 раза.
Про то, как устроен float внутри – рассказывать не буду. У Никиты Соболева недавно было большое и подробное видео на тему внутреннего устройства float. У него действительно хороший технический контент, советую подписаться: @opensource_findings
Итого
Если у вас нет требований по работе именно с десятичной записью числа (как, например, в бухгалтерии), то используйте float. Он даст достаточную точность и хорошую скорость. Если вы хотите, чтобы расчеты велись в десятичных цифрах и ваши расчеты построены так, что абсолютная точность достижима, то используйте Decimal.
Дополнительные материалы:
• https://www.youtube.com/@sobolevn/
• https://0.30000000000000004.com
• https://en.wikipedia.org/wiki/X87
• http://aco.ifmo.ru/el_books/numerical_methods/lectures/app_1.html
Вас никогда не удивляло, что
0.1 + 0.2 != 0.3? Почему float считает с погрешностями, и всем норм?Дело в том, что
0.1 выглядит как0 0111111101 11001100110011001100110011001100110011001100110011010.
Где:
•
0 обозначает знак + (и 1 обозначает -)•
0111111101 обозначает exponent, равную 0^10 + 2^9 + 2^8 + 2^7 + 2^6 + итд = 1019. Вычтем 1023 (размерность double) и получим итоговое значение: 1019 - 1023 = 4•
11001100110011001100110011001100110011001100110011010 обозначет "significand" или "мантису", которая равна: 2^-exp + 2^-exp-1 + 2^-exp-2 + итд ~= 0.1Вот так мы можем примерно представить 0.1 в виде float. Примерно – потому что все вычисления идут с погрешностью. Мы можем проверить данное утверждение, добавив погрешность вручную:
>>> assert 0.1 + 2.220446049250313e-18 == 0.1
Значение внешне не изменилось при добавлении погрешности. Посмотрим на sys.float_info.epsilon, который устанавливает необходимый порог для минимальных отличий 1.0 от следующего float числа.
>>> import sys
>>> sys.float_info.epsilon
2.220446049250313e-16
>>> assert 1.0 + sys.float_info.epsilon > 1.0
>>> assert 1.0 + 2.220446049250313e-17 == 1.0 # число меньше epsilon
Как конкретно будет выглядеть
0.1? А вот тут нам уже поможет Decimal для отображения полного числа в десятичной системе:>>> decimal.Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
И вот ответ про 0.1 + 0.2, полное демо с битиками:
>>> decimal.Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> decimal.Decimal(0.2)
Decimal('0.200000000000000011102230246251565404236316680908203125')
>>> decimal.Decimal(0.1 + 0.2)
Decimal('0.3000000000000000444089209850062616169452667236328125')
>>> decimal.Decimal(0.3)
Decimal('0.299999999999999988897769753748434595763683319091796875')
Числа не равны друг другу, потому что их разница больше предельной точности float. А сам Decimal может использовать любую точность под задачу.
>>> from decimal import Decimal, getcontext
>>> getcontext().prec = 6
>>> Decimal(1) / Decimal(7)
Decimal('0.142857')
>>> getcontext().prec = 28
>>> Decimal(1) / Decimal(7)
Decimal('0.1428571428571428571428571429')
Но и
Decimal не может в абсолютную точность, потому что есть в целом невыразимые в десятичной системе числа, такие как math.pi, ⅓, тд. С чем-то из них может помочь fractions.Fraction для большей точности, но от существования иррациональных чисел никуда не деться.Почему всем норм, что у нас с
float такие погрешности в вычислениях? Потому что во многих задачах абсолютная точность недостижима и не имеет смысла. Благодаря плавающей точке мы можем хранить как очень большие, так и очень маленькие числа без существенных затрат памяти. А ещё float - очень быстрый. В том числе за счет аппаратного ускорения.» pyperf timeit -s 'a = 0.1; b = 0.2' 'a + b'
.....................
Mean +- std dev: 8.75 ns +- 0.2 ns
» pyperf timeit -s 'import decimal; a = decimal.Decimal("0.1"); b = decimal.Decimal("0.2")' 'a + b'
.....................
Mean +- std dev: 27.7 ns +- 0.1 ns
Разница в 3 раза.
Про то, как устроен float внутри – рассказывать не буду. У Никиты Соболева недавно было большое и подробное видео на тему внутреннего устройства float. У него действительно хороший технический контент, советую подписаться: @opensource_findings
Итого
Если у вас нет требований по работе именно с десятичной записью числа (как, например, в бухгалтерии), то используйте float. Он даст достаточную точность и хорошую скорость. Если вы хотите, чтобы расчеты велись в десятичных цифрах и ваши расчеты построены так, что абсолютная точность достижима, то используйте Decimal.
Дополнительные материалы:
• https://www.youtube.com/@sobolevn/
• https://0.30000000000000004.com
• https://en.wikipedia.org/wiki/X87
• http://aco.ifmo.ru/el_books/numerical_methods/lectures/app_1.html
👍2
Статья: чему меня научила разработка продукта с нуля
Насколько сложно запустить мобильное приложение? Сколько микросервисов и строк кода нужно для прототипа? @saluev рассказывает, как делал бэкенд для стартапа в одиночку, что получилось и чему удалось научиться. Под катом даже есть некоторое количество кода на питоне.
Читать целиком на Хабре: https://habr.com/ru/articles/889758/
Насколько сложно запустить мобильное приложение? Сколько микросервисов и строк кода нужно для прототипа? @saluev рассказывает, как делал бэкенд для стартапа в одиночку, что получилось и чему удалось научиться. Под катом даже есть некоторое количество кода на питоне.
Читать целиком на Хабре: https://habr.com/ru/articles/889758/
Хабр
Урок ценой $115 000: чему меня научила разработка продукта с нуля
Последние пару лет в свободное от Настоящей Работы время я в роли CTO/соло-бэкендера участвовал в создании Stry — фитнес-стартапа с подписной моделью. Теперь, когда наша команда официально объявила о...
👍6❤🔥1✍1🔥1😨1
Статья: год с Dishka: какой он — модный DI-контейнер?
@bomzheg рассказывает, как он использует Dishka в своём open source-проекте для городской игры. Код до, код после и рассказ про то, как работать с Dishka в e2e-тестах.
Читать целиком на Хабре: https://habr.com/ru/sandbox/241258
@bomzheg рассказывает, как он использует Dishka в своём open source-проекте для городской игры. Код до, код после и рассказ про то, как работать с Dishka в e2e-тестах.
Читать целиком на Хабре: https://habr.com/ru/sandbox/241258
Хабр
Год с Dishka: какой он — модный DI-контейнер?
Привет, Хабр, меня зовут Юрий, я уже год использую хайповый IoC‑контейнер dishka в python-проекте и хочу немного поделиться опытом эксплуатации. Мой проект — движок для городской ночной...
❤9❤🔥2
Статья: как я стал core-разработчиком Python в 19 лет
Как начать контрибьютить в опенсорс? Насколько быстро можно добиться результатов? @backinblacknext рассказывает, как он попал в команду разработки интерпретатора CPython — начиная с правок в документацию и заканчивая статусом core-разработчика со 138 смерженными пулл-реквестами.
Читать целиком на Хабре: https://habr.com/ru/articles/899636/
Как начать контрибьютить в опенсорс? Насколько быстро можно добиться результатов? @backinblacknext рассказывает, как он попал в команду разработки интерпретатора CPython — начиная с правок в документацию и заканчивая статусом core-разработчика со 138 смерженными пулл-реквестами.
Читать целиком на Хабре: https://habr.com/ru/articles/899636/
Хабр
Как я стал core-разработчиком Python в 19 лет
20 сентября 2024 года я стал одним из участников команды разработки CPython. Что значит CPython Core developer? CPython Core Developer — это core-разработчик, имеющий официальные полномочия вносить...
👍8❤🔥3🍌3🔥1
🔔 Relator от reagento (@smqwe12 и @Tishka17) — это GitHub Action, который позволяет отправлять уведомления о новых issues и PRs в телеграм.
Решение было разработано, т.к. все существующие альтернативы требуют админский доступ от вашего аккаунта для всех групп, в которых вы состоите, что достаточно небезопасно. Проект находится в активной разработке, но основной функционал уже активно используется и стабильно работает.
Мы открыты для ваших идей и правок, поэтому приносите их :)
Ключевые преимущества:
- Ограниченный scope токена для работы с вашими репозиториями
- Возможность переопределять шаблоны сообщений
- Полноценная поддержка форматирования текста
Быстрый старт:
Примеры использования:
– FastStream
– Dishka
– wemake-python-styleguide
💻 Репозиторий
🚀 Группа
Решение было разработано, т.к. все существующие альтернативы требуют админский доступ от вашего аккаунта для всех групп, в которых вы состоите, что достаточно небезопасно. Проект находится в активной разработке, но основной функционал уже активно используется и стабильно работает.
Мы открыты для ваших идей и правок, поэтому приносите их :)
Ключевые преимущества:
- Ограниченный scope токена для работы с вашими репозиториями
- Возможность переопределять шаблоны сообщений
- Полноценная поддержка форматирования текста
Быстрый старт:
- name: Send Telegram notification
uses: reagento/relator@v1.5.0
with:
tg-bot-token: ${{ secrets.TELEGRAM_BOT_TOKEN }}
tg-chat-id: ${{ vars.TELEGRAM_CHAT_ID }}
github-token: ${{ secrets.GITHUB_TOKEN }}
Примеры использования:
– FastStream
– Dishka
– wemake-python-styleguide
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍5👏2😁1
CayleyPy — open-source Python библиотека, применяющая методы искусственного интеллекта для решения задач теории графов и групп.
Если вы интересуетесь Python, графами или просто хотите поучаствовать в крутом научно-техническом проекте — присоединяйтесь! Математическая подготовка не обязательна — достаточно любопытства и желания внести вклад в open source. При активном участии Вы станете соавтором публикаций на А-стар конференциях. (Пинганите @alexander_v_c)
Основные особенности CayleyPy:
🧠 Использует методы искусственного интеллекта и обучения для исследования структур графов и групп
⚡️ Поддерживает генерацию и анализ Cayley-графов любой сложности
📊 Содержит инструменты для автоматического вывода математических гипотез
🔍 Полностью open source, с открытой документацией и активным сообществом
🧩 Простая архитектура — подключайтесь и экспериментируйте прямо из Python
💻 Репозиторий проекта
📚 Документация
🚀 RU Telegram
Если вы интересуетесь Python, графами или просто хотите поучаствовать в крутом научно-техническом проекте — присоединяйтесь! Математическая подготовка не обязательна — достаточно любопытства и желания внести вклад в open source. При активном участии Вы станете соавтором публикаций на А-стар конференциях. (Пинганите @alexander_v_c)
Основные особенности CayleyPy:
🧠 Использует методы искусственного интеллекта и обучения для исследования структур графов и групп
⚡️ Поддерживает генерацию и анализ Cayley-графов любой сложности
📊 Содержит инструменты для автоматического вывода математических гипотез
🔍 Полностью open source, с открытой документацией и активным сообществом
🧩 Простая архитектура — подключайтесь и экспериментируйте прямо из Python
📚 Документация
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
С 1 по 12 декабря на Advent of Code выкладываются алгоритмические задачки, от простых до довольно сложных. Как участвовать: создайте аккаунт на Advent of Code (рекомендую через гитхаб) и вступайте в наш приватный лидерборд. Пароль для вступления:
83029-622626d1Всем удачи!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5