import __hello__
244 subscribers
5 photos
38 links
Канал про IT, здебільшого WEB та Python, але буває й у інші теми заносить
Download Telegram
Усі ж чули про ruff? Це такий лінтер all-in-one для пайтону написаний на Rust. Головна його конкурентна фішка - це швидкість, він дійсно значно швидший ніж будь який інший лінтер для пайтону, вміє автоматично фіксити код, а ще у нього можливо навіть інтегрують black та mypy.

Останній рік він був на хайпі - новини, твіттер, різні проєкти переводили на нього свої CI (один із таких проєктів FastAPI). А нещодавно автори цього лінтера заснували свою компанію Astral яка одразу ж підняла 4 мільйони доларів.

Мені уся ця метушня навкого ruff не подобається з таких причин:

1. Автори беруть вже існуючі лінтери та переписують їх на Rust (не хочу вчити раст щоб писати собі тулінг).
2. Плагіни для flake8 продовжують розвиватись і оновлюватись і ruff не завжди встигає за цим стежити. Та й взагалі імплементація у ruff може відрізнятись від оригіналу чи не містити частини функцій
3. Навідміну від flake8 ця штука моноліт і не має системи плагінів. Тобто якщо для flake8 я можу написати свій плагін, опублікувати його у pypi, використовувати й росповсюджувати, то для ruff мені треба робити МР у їх проєкт, чекати апрувів (якщо вони будуть) і чекати поки то потрапить у нову версію
4. Найбільша моя претензія - Python розробники не можуть вносити вклад у лінтер для пайтону, бо він написаний на зовсім іншій мові (дивись попередній пункт, навіть плагіни писати не можуть на расті). А дивлячись на зростаючу популярність ruff у мене це викликає побоювання що через нього flake8 та інші лінтери написані на пайтоні перестануть розвиватись, як наслідок - уся екосистема лінтерів буде залежати від проєкту на расті у котрий контрибьютить 2.5 розробника.

А ось сьогодні Anthony Sottile, мейнтейнер flake8, багатьох плагинів для flake8 і інших різних лінтерів висказав свою думку на рахунок ruff у відео. Якщо коротко:

1. Ruff це дуже вражаюче ПО яке робить багато крутих штук.
2. Автори Ruff скопіювали дуже багато результатів роботи пайтон комьюніті (специфічно частину яка про лінтери) за останні 15-20 років та переписали їх на Rust
3. Попередній пункт звісно не порушує жодних ліцензій (ліцензії коду який за основу взяв ruff це дозволяють)
4. Претензія Anthony у тому що ruff узяв результати роботи і нічого не віддав взамін
5. Більше того, була заснована компанія навколо ruff, яка зібрала 4 мільйони доларів і жодна частина цих коштів не була віддана на спонсорство flake8 чи інших проєктів без яких ruff просто би не існувало
6. Anthony засмучений через те що ruff "вбив" багато проєктів над якими він працював і він більше не бачить стимулів далі працювати над цими проєктами
7. Ruff це дуже вражаюче ПО, але їх підхід брати результати чиєїсь роботи і не віддавати нічого взамін "kinda sucks"

Звісно автори ruff мали повне право зробити те що вони зробили, але з етичної точки зору це не зовсім ок, і я розумію автора відео.

Я на ruff не спішив переходити з причин описаних у першій частині цього тексту і ще через те що у нього немає деяких плагінів котрими я користуюсь, а швидкість flake8 достатня, особливо якщо використовувати pre-commit котрий вміє запускати лінтери лише для змінених файлів. Тому я на ruff світчитись не планую і сподіваюсь що у flake8 та взагалі у лінтерів для пайтону написаних на пайтоні все буде добре.
Моноліт, мікросервіси, поліліт?

У сучасному світі розробки поширена думка, що моноліт застарів, а мікросервіси — єдиний правильний шлях побудови систем. Звісно, я трохи перебільшую, тим паче що час, коли кожна поважаюча себе компанія, мала у своєму блозі статтю про перехід від моноліту до 300 і більше мікросервісів, минув. Проте й досі часто розробники при старті нового проєкту одразу починають з мікросервісної архітектури. Але скоріш за все то не дуже гарна ідея і почати варто б було з побудови моноліту.

Бо починаючи новий проєкт, ви ще не знаєте, як правильно вибудувати bounded context і не розумієте меж доменних областей. Тому, у процесі розробки, вони будуть змінюватися: деякі сутності переходитимуть з одного контексту в інший, контексти дробитимуться та об'єднуватимуться, бізнес вимоги будуть постійно змінюватись. Таким чином, ваша система буде інтенсивно еволюціонувати, поки ви шляхом проб та помилок не визначите правильні межі. Такі великі зміни робити коли у тебе все побудовано на мікросервісах досить боляче. Більш доцільно почати з моноліту, а в процесі розробки та експлуатації, коли будете впевнені в правильності визначених bounded contexts, поступово "від'єднувати" частини системи в мікросервіси. Звичайно, не варто створювати мікросервіси лише тому, що так роблять усі. Це має бути обгрунтовано: можливо, частина вашої системи має вище навантаження і, виносячи її в окремий сервіс, ви зможете ефективніше масштабуватись; або в різних частинах системи можуть бути різні SLA та вимоги до безпеки; чи ви хочете передати частину системи в управління окремій команді, тощо. Гарний допис про те чому не варто стартувати з мікросервісів є у Мартіна Фаулера

Проте, ті, хто хоч раз спробував розділити вже існуючий, можливо застарілий, моноліт, скажуть, що це не просто. Сильна сторона моноліта "легкість змін" має зворотній бік — дуже легко побудувати систему із високою зв'язністю (high coupling), через що розбиття моноліту на окремі мікросервіси може бути настільки складним, що простіше переписати систему з нуля. Тому, щоб вирішити цю проблему, розумні люди придумали таку штуку як "модульний моноліт".

Модульний моноліт — це архітектурний прийом, що поєднує елементи монолітної архітектури з модульним підходом. Код розділений на модулі з чіткими межами в рамках одного додатку. Кожен модуль відповідає за певну функціональність і характеризується високою когезією та слабкою зв'язністю з іншими модулями. Слабка зв'язаність досягається завдяки комунікації між модулями через добре пропрацьований публічний API. Модулі можуть взаємодіяти як через прямі виклики методів, так і асинхронно через черги повідомлень, що ускладнює проектування, але спрощує перехід до мікросервісів (у разі необхідності). Кожен модуль представляє окремий bounded context, тож, якщо потрібно розділити моноліт на мікросервіси, це буде легко зробити. Ще один плюс такого підходу - ви можете ділити модулі між командами, тобто одна команда може ексклюзивно овнити один чи декілька модулів.

Більш детальний приклад модульного моноліту можно подивитись тут

Можливо, наступного разу розповім про наявні інструменти для Python, що сприяють побудові модульних монолітів.

Лінки:
- Дуже багато матеріалів по темі
- Monolith First
- Microservices Killer: Modular Monolithic Architecture
- microservices.io
Відосики про нормалізацію та денормалізацію SQL БД. Загальна інфа, але може бути корисною тим хто до співбесіди готується, освіжити знання, чи просто подобаються технічні відосики з гарним відеорядом.
Тут Dave Plummer твітнув дуже повчальну історію про те як він у 94 році накидав тимчасовий UI для діалогу форматування диску у WindowsNT. І ось вже минуло 30 років, а ви й досі у актуальній версії Windows можете відкрити цей "тимчасовий" діалог і подивитись на результат його роботи 😁

Мораль всім відома - немає нічого більш постійного аніж тимчасове, тому коли робите щось "тимчасове" у кодовій базі, потурбуйтесь про те щоб воно було достатньо оптимальне і вам не довелось надто червоніти за свої рішення, бо скоріш за все результати вашої роботи буде спостерігати ще не одне нове покоління програмістів 😁

Доречі у цього чувака є прикольний канал на ютубі про DIY, C++ та історію Windows.

Лінки:
- https://twitter.com/davepl1968/status/1772042158046146792
- https://www.youtube.com/@DavesGarage
Вийшов новий Technology Radar. Із цікавого (мені):
- Text to SQL in Trial (новий)
- CloudEvents in Adopt (піднявся із Trial)
- Pulumi in Trial (минулого разу також був у Trial)
- Rancher Desktop (новий, витиснув Colima)
- Kaniko in Adopt (минулий раз згадували у 2022 році)
- Mojo in Assess (новий)

Знов багато AI та не дуже багато чогось кардинально нового. Але може хтось для себе щось цікаве відкриє (мені не вдалось цього разу, хіба що Kaniko)

https://www.thoughtworks.com/radar
Forwarded from Алекс про усе
Дядько Боб на твічі – залітайте)

https://www.twitch.tv/ThePrimeagen

P.S. Це автор багатьох книг по програмуванні і хорошому коду. Якщо не читали дуже рекомендую
Додивився серіал по Fallout і ось що я можу сказати як фанат 1, 2 частини, New Vegas та хейтер частин від Bethesda.

Загалом непоганий серіал, на 3 з плюсом. Із бісячого:
- Антураж схоже що взяли за основу із 4 частини - замість похмурого і сірого цвітасте та веселе
- Постанову масових перестрілок та бійок взагалі з трейлерів 4 та 76: всі бʼються під веселу музичку у слоумо
- Головний герой знову шукає свого родича, знов батька - або сценаристи Bethesda мають якісь дитячи травми, або вони великі фанати останніх Форсажів (головне - сімʼя), інших пояснень у мене немає
- Немає супермутантів
- Взагалі дуже мало канонічних монстрів, мабуть бюджет не дозволив
- Кігтя смерті показали лише у якості черепа
- Персонажів гри, які могли дожити до часу у який відбуваються події серіалу немає, хоча тут я може неуважно дивився
- Якась дурня із штукою за котрою увесь сезон полюють усі кому не лінь

Із того що сподобалось:
- Братство Сталі - покидьки
- Показали молодого Містера Хауса
- Не було відсилок до Легіону
- Загалом є відсилки до New Vegas, а другий сезон можливо взагалі буде про Вегас

Можна дивитись, я мабуть й другий сезон гляну як вийде

Так, це все ще канал про IT)
Добре, поки мене не було я не лише серіали дивився, я також встиг написати ще одну DI бібліотеку для Python 😎.

Навіщо то взагалі у Пайтоні? Ну сама концепція DI це дуже крута штука, яку можна використовувати будь де без усіляких фреймворків. Але у такому разі треба самому бутстрапити залежності при старті апки і думати як оверайдити залежності у тестах. До того ж скоріш за все це все скатиться у service locator та нескінченні if my_service is None: my_service = get_my_service().

Раніше я користувався dependency-injector. Це чудова ліба, але вона завжди здавалась мені дуже навороченою для моїх цілей. І якщо на робочих проєктах її використання ще якось було виправдано, то для маленьких pet-проєктів це точно оверкіл - я завжди починаю з перечитування документації перш ніж засетапити новий проєкт із цією лібою. До того ж вона вже 2 роки не розвивається, тому я почав шукати альтернативи.

Мені подобається концепція DI у FastAPI - залежності це звичайні функції, ніяких контейнерів чи цілої пачки різних типів провайдерів - якщо хочеш щоб твоя залежність була кешованою - просто оберни її у lru_cache.

Із того що я знайшов цікавого у pypi:
- FastDepends - типу як у FastAPI, але із якимись лівими функціями, інколи скаржиться на аргументи які не мають інжектитись через тайп анотації, не має ресурс менеджменту і не може ніяк засунути async залежність у sync функцію, навіть якщо ми вже у async контексті, а ще не дуже дружить із FastAPI 🤯
- picobox - дуже крута концепція, але функціонал в основному зусереджений на Scopes (щоб залежності кешувались як сінглтон, у треді, у асінк тасці, реквестах, тощо), не має ресурс менеджменту і не дуже дружить із тайп анотаціями
- injector - стара ліба, мабуть непогана, але мені ніколи не подобався її API
- di та rodi - це більше схоже на ресолвери залежностей, над якими ще треба побудувати свій зручний API, хоча я може і помиляюсь

Тобто нічого із того що я знайшов мені не підходить. А мені усього то потрібно:
1. Власне інжекція залежностей у аргументи функцій, було б гарно якби як у FastAPI
2. Менеджмент ресурсів - щоб можна було зробити залежність яка має teardown і кешує свій результат впродовж життя апки - зручно для конекшенів у БД
3. Можливість оверайдити залежності для тестів
4. Зручний API і без зайвих можливостей

Тож я написав picodi (спочатку це мало бути nanodi, але pypi сказав що імʼя дуже схоже на вже існуючу лібу і не дав створити із такою назвою)- по суті це декоратор котрий резолвить (просто викликає функцію) залежності і сує їх у декоровану функцію, усе. Із додаткових можливостей - ресурс менеджмент, оверайдинг залежностей, працює із FastAPI і бонус - можливість резолвити асинхронну залежність-ресурс у синхронну функцію і ніякого вайрінгу (і ніякого детекту циклічних залежностей також 😁). Можливо імплементація трохи наївна, але поки мені подобається - я вже замінив dependency-injector на декількох своїх pet-проєктах без якихось проблем.

Тож якщо у когось з вас є схожі вимоги до DI фреймворку - можете спробувати, та не соромтесь робити issues та PR's 😊.

https://github.com/yakimka/picodi
У Django зʼявляться background workers

Декілька днів тому прийняли DEP-14, наступним кроком буде власне імплементація. Як я зрозумів вони просто зроблять django-tasks частиною Django.
Не те щоб мене ця новина якось обходила, бо я вже давно з Джангою справ не маю (ну майже) але це гарна пропозиція, бо майже будь яка апка на Django трохи більша ніж hello world потребує можливості запускати таски у фоні, а не заставляти юзера чекати її виконання.
Усі для цього використовували Celery, але ця ліба досить велика та потужна і до того не завжи тривіальна у налаштуванні і коли тобі треба зробити лише одну-дві простих дії у бекграунді то тащити цю монструозну лібу не дуже хочеться.
Ну от тепер і не треба буде - у Джанзі і для цього тепер буде рішення "із коробки".
import __hello__
Добре, поки мене не було я не лише серіали дивився, я також встиг написати ще одну DI бібліотеку для Python 😎. Навіщо то взагалі у Пайтоні? Ну сама концепція DI це дуже крута штука, яку можна використовувати будь де без усіляких фреймворків. Але у такому…
Доречі, коли хочеться почати свій пет-проєкт який щось для мене покращить, чи просто just for fun, то треба якнайшвидше приступити до реализації, поки не перегоріло.
Бо поки засетапиш проєкт: додаси лінтери, сконфігуруєш їх, наставиш улюблених плагинів для пайтеста, напишеш Makefile, напишеш workflow для github actions (клятий github actions) - вже пройде декілька днів і бажання щось робити пропаде 😁.
А просто робити щось без цієї автоматизації і собі ж дорожче і не в кайф.

Тому одного разу я зробив собі шаблон для python-проєктів і одразу відчув користь:

- Не треба переносити сетап із минулого проєкту попутньо вирізаючи неактуальні частини конфігів і роблячи перейменування
- При створенні проєкту з шаблону можна робити різні налаштування і включати\виключати потрібні компоненти в новий проєкт. Наприклад якщо планується використовувати pydantic - одразу додати відповідний плагін до mypy
- Так як шаблон це тепер також мій окремий проєкт - він так само як будь який інший проєкт еволюціонує
- Dependabot допомагає слідкувати за актуальністю залежностей у шаблоні

Іншими словами, коли мені хочеться щось нове зробити, я просто запускаю команду і через секунду в мене вже готовий сетап під новий проєкт, налаштований так як мені подобається.
Тому дуже рекомендую зробити для себе такий шаблон щоб кожного разу не витрачати час на одну й ту саму рутину.

Лінки:
- Cookiecutter - менеджер для таких от шаблонів. Не обовʼязково шаблон має бути для пайтона - це може бути шаблон будь чого, навіть не обовʼязково звʼязаний із програмуванням
Подивився на ютубі інтервʼю з чуваком, який переписав кафку.

⁃ написали все на golang. Сказав, що це мова, до якої немає питань. Типа вони з напарником ніколи її не обговорюють, а просто деліверять фічі;

⁃ в якості стореджа використовується S3. Це дає доволі суттєву економію, порівняно з EBS (що є по суті клаудним NAS на SSD). По суті це реальний cloud native storage, який може скейлитись до нескінченності і має майже 100% SLA. Недоліком є трохи вища latency;

⁃ хочуть повністю повторити протокол kafka, зараз вже все є, крім транзакцій. По суті це drop in replacement для кафки, і існуючі клієнти можуть перемкнутись на їхній сервіс без змін (якщо там немає транзакцій);

⁃ ноги у проекта ростуть з DataDog -- на початку є пара цікавих інсайдів про внутрянку останніх;

⁃ під час написання намагаються не дивитись на код kafka (який на java), натомість використовують код альтернативних клієнтів. Бо протокол дуже складний, мало документований, а в сторонніх клієнтах часто можна знайти коменти про реалізацію підтримки нововведень і різних corner cases

В цілому дуже сподобалось і саме інтервʼю, і проект який вони замутили. Ось посилання, якщо хочете подивитись самі: https://www.youtube.com/watch?v=xgzmxe6cj6A. Крім того, шо я тут написав, там багато цікавого про реалізацію, виклики, що стоять перед подібними системами, мотивацію і тд.

А це власне їхній стартап: https://www.warpstream.com/
Натрапив на просторах реддіта на репозиторій із переліком штук про котрі треба пам'ятати коли пишеш веб-сервіс на FastAPI.
Їх там зараз небагато, але всі дуже важливі. Мене найбільше зацікавив 9 пункт "Your dependencies may be running on threads" -
це може бути неочевидним, але якщо ваша async def view використовує синхронну залежність (навіть якщо вона нічого не робить а просто повертає примітивне значення)
то резолвінг цієї залежності буде відбуватись у тредпулі.

Тобто ось у цьому прикладі буде використовуватись тредпул незважаючи на те що root view використовує async def:


from fastapi import FastAPI, Depends

app = FastAPI()

def get_42():
return 42

@app.get("/")
async def root(value: int = Depends(get_42)):
return {"value": value}


Чим це погано? Тим що треди не резинові і за замовченням одночасно може жити лише 40 тредів, і якшо на ваш ендпоінт буде наплив трафіку, то перші 40 реквестів забʼють
тредпул, а решта буде чекати поки звільниться місце. Звісно що значення по-дефолту можна підняти, але воно всеодно не буде нескінченним.
Виправити у прикладі вище цю проблему просто - замінити def get_42(): на async def get_42(): і тоді всі реквести
будуть запускатись без тредпула, просто у поточному event loop.

Підсумовуючи:
- Завжди у першу чергу використовуйте async def для вьюх (це вже й так всі запамʼятали) і залежностей що інжектяться через Depends.
- Синхронні вьюхи використовуйте лише якщо вони роблять блокуючі операції, наприклад використовують бібліотеку requests для http запитів.
- Перевірте свої додатки - у тому ж пункті є код за допомогою якого можна це зробити

Лінки:
- https://github.com/Kludex/fastapi-tips
Мабуть не відкрию ні для кого Америку, але метадата про кожний пакет у pypi, кількість скачувань і інша інформація доступна у публічному BigQuery.
Тож можна отримати будь яку цікаву для вас інформацію. Ось мені було цікаво знайти нові плагіни для flake8.


SELECT
name,
CONCAT('https://pypi.org/project/', name) AS project_url,
MAX(upload_time) AS most_recent_upload_time
FROM
`bigquery-public-data.pypi.distribution_metadata`
WHERE
name LIKE 'flake8-%'
GROUP BY
name
ORDER BY
most_recent_upload_time DESC


Звісно ганьба що pypi сам не дає способу нормально шукати по назвам та не показує кількість скачувань пакетів, але маємо що маємо.

Лінки:
- https://packaging.python.org/en/latest/guides/analyzing-pypi-package-downloads/#public-dataset
- https://console.cloud.google.com/bigquery?p=bigquery-public-data&d=pypi&page=dataset
У соурскоді sqlite 😁

За замовчуванням префікс був "sqlite". Але потім Mcafee почала використовувати SQLite у своєму антивірусному продукті, і він почав створювати файли з назвою "sqlite" у папці c:/temp. Це дратувало багатьох користувачів Windows. Ці користувачі шукали в Google "sqlite", знаходили номери телефонів розробників і телефонували їм уночі, щоб поскаржитися. З цієї причини префікс назви за замовчуванням було змінено на "sqlite", написане навпаки. Таким чином, тимчасові файли все ще можна ідентифікувати, але будь-хто, достатньо розумний, щоб зрозуміти код, також, ймовірно, достатньо розумний, щоб знати, що дзвінок розробнику не допоможе позбутися файлу.
import __hello__
Опублікували відоси із PyCon US 2024 https://www.youtube.com/playlist?list=PL2Uw4_HvXqvYhjub9bw4uDAmNtprgAvlJ
Виявляється що у coverage.py є альтернатива - Slipcover. Це така сама тулза для виміру покриття проєкту тестами але усього із 5% оверхеда у швидкодії (Coveragepy робить виконання вашого коду у три рази повільнішим, для порівняння).
На великих проєктах втричі більш швидкі тести це дуже суттєво.

Ще цікава штука, у цьому докладі автор обмовився що із 5% оверхедом це можна ганяти і у продакшені. Тобто можна запустити прям свій веб сервер через цю тулзу і побачити чи є у проєкті "мертві" куски коду, котрі ніколи не викликаються, прям богата ідея.
Сьогодні на leetcode.com problem of the day це просто написати якийсь алгоритм сортування, тому ось вам стаття про те як імплементувати найпопулярніші із них із бенчмарками та переліком їх плюсів та мінусів.

Доречі ви знали що саме для Python вигадали новий алгоритм сортування Timsort (отримав назву по імені того хто його вигадав - Тім Пітерс)?
І що на співбесідах його ніхто ніколи не пише, бо для його імплементації спочатку треба написати insertion та merge алгоритми 😁.
Потім цей алгоритм утягнули до себе Swift, V8 та Rust.

Лінки:
- https://realpython.com/sorting-algorithms-python/
- https://en.wikipedia.org/wiki/Timsort
Мені подобається у якому напрямку рухається розвиток Python зараз.
Як на мене, нагальної потреби у додаванні нових фічей у мову зараз немає - вона вже досить давно є зрілою і містить достатню кількість мовних фічей (деякі із котрих можливо треба б було задепрекейтити і видалити)
І те що вже декілька версій у пайтон не додається багато нових можливостей (маю на увазі різний синтаксичний цукор) а навпаки core-розробники сконцентрували свою уваги над поліруванням того що є (покращують REPL, роблять повідомлення про помилки більш інформативними, видалять застарілі частини стдлібу, тощо) та над прискоренням CPython (nogil, JIT, subinterpreters, та звичайні оптимізації) як на мене дуже гарний знак того що у мови буде ще багато років планомірного розвитку.

Ось і новий реліз йде у сторону поліпшення швикодії та покращення developer expirience:

https://www.youtube.com/watch?v=gqqgwyNx52Q
Якось випадково натрапив на відос "Why don't Americans use electric kettles?" (ютуб рекомендації іноді підкидають щось неочікуване) і залип.
Саме так виглядав би ютуб канал гіка з 60х 😁. Автор бере якусь стару технологію і розповідає про неї так нібито це щойно презентований айфон чи макбук "The Antique Toaster that's Better than Yours"

Або ось він досліджував наскільки сильно зовнішні навіси на вікна охолоджують будинок у літню спеку і чому їх більше не використовують, чи про проблеми які зʼявились у інженерів котрі проєктують автомобільні стоп-сигнали із появою електрокарів.
Коротше якщо вам також подобаються гіковскі відоси із акцентом на старі технології - дуже рекомендую

Лінки:
- https://www.youtube.com/@TechnologyConnections
Стаття про фічі нового Python 3.13. Ні, не про noGIL, JIT та інше, а про зміни які ви скоріш за все оминули увагою

https://www.bitecode.dev/p/python-313-what-didnt-make-the-headlines