import __hello__
278 subscribers
16 photos
55 links
Канал про IT, здебільшого WEB та Python, але буває й у інші теми заносить
Download Telegram
import __hello__
Ну що, розпочався черговий Advent of Code - гарний спосіб відволіктись від буденного життя і отримати трохи новорічного настрою. Цей івент також може стати гарною нагодою вивчити\підтягнути нову мову програмування (чи навіть технологію, бачив пости де чуваки…
Це перший рік коли я закінчив івент день у день і на всі 50 зірочок. Цього року навіть вдалось підбити декількох знайомих також приймати участь, тому було цікавіше ніж зазвичай.

Мені сподобалось, із плюсів участі у таких івентах можу назвати:
- трохи тримає тебе у "програмерскій формі", якщо немає звички й так протягом року задротити літкод
- дізнаєшся про різні цікаві проблеми і алгоритми із реального життя. Наприклад цьогоріч я дізнався про алгоритм Брона-Кербоша
- а у минулому році дізнався про крутезний блог https://www.redblobgames.com коли шукав інформацію про Дейкстра та A* алгоритми

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

Коротше прикольний івент, допомагає якось відволіктись та підготуватись до пошуку нової роботи згадати що програмування це не лише перекладання джейсончиків із бази у http-api 😁
👍134🎉3🎄3🔥2🏆1
З НР!🎄
14👍10🍾5
Якщо ви використовуєте pickledb (сподіваюсь що для прототипів, а не для "продакшену"), то для вас новина: її автор випустив вдосконалену версію - kenobiDB, він каже що це більш пропрацьована тред та процес безпечна документна база даних котру він сам використовує у своїх прототипах (а про pickledb він пише "what I now consider very stupid and useless" 🙃).

І якщо ми вже згадали embeded бази даних для пайтону, то щоб два рази не вставати давайте я залишу перелік тих про котрі знаю і котрими користувався (інколи із них дуже зручно почати MVP а потім перемкнути імплементацію на щось "доросле", якщо у цьому буде потреба)

1. montydb

Embeded база даних "яка виглядає і працює як MongoDB". Із документації - лише рідмі у проєкті 😄


>>> from montydb import MontyClient

>>> col = MontyClient(":memory:").db.test
>>> col.insert_many( [{"stock": "A", "qty": 6}, {"stock": "A", "qty": 2}] )
>>> cur = col.find( {"stock": "A", "qty": {"$gt": 4}} )
>>> next(cur)
{'_id': ObjectId('5ad34e537e8dd45d9c61a456'), 'stock': 'A', 'qty': 6}


2. tinydb

Проєкт яким надихався montydb - теж embeded, теж документоорієнтовна, вміє бути drop-in заміною монги через екстеншен tinymongo. Навідміну від montydb має документацію та більшу кількість підтримки на гітхабі (зірочки, коміти, котрибутори)


>>> from tinydb import TinyDB, Query
>>> db = TinyDB('/path/to/db.json')
>>> db.insert({'int': 1, 'char': 'a'})
>>> db.insert({'int': 1, 'char': 'b'})


3. mongita

Mongita is to MongoDB as SQLite is to SQL. Ще одна ліба котра намагається бути заміною монги, але останній коміт у репі був аж 2 роки тому.


>>> from mongita import MongitaClientDisk
>>> client = MongitaClientDisk()
>>> hello_world_db = client.hello_world_db
>>> mongoose_collection = hello_world_db.mongoose_collection
>>> mongoose_collection.insert_many([{'name': 'Meercat', 'does_not_eat': 'Snakes'},
{'name': 'Yellow mongoose', 'eats': 'Termites'}])


Лінки:
- https://github.com/patx/kenobi
- https://www.reddit.com/r/Python/comments/1hqvrd6/kenobidb_30_made_public_pickledb_replacement/
- https://github.com/davidlatwe/montydb
- https://github.com/msiemens/tinydb
- https://github.com/scottrogowski/mongita
👍7🔥2
😁17🤔1👀1
І так всюду і з усім 🙂
😁19
Ого, не знаю що сталось, але MongoDB випустили офіційний бекенд для Django. Він поки що Public Preview та рекомендований лише для ознайомлення.
Прям максимально неочікувана новина для мене, бо, принаймні у моїй бульбашці, джанго потихеньку здає позиції і все частіше замість неї обирать FastAPI або ще якийсь із сотні асинхронних мікрофреймворків. До того ж дивно чого саме бекенд для Джанги, а не для SqlAlchemy? Але прикольно - якщо дотягнуть до реліза то популярність Джанги може трошки знову піти вгору 😅

Лінки:
- https://www.mongodb.com/docs/languages/python/django-mongodb/current/
- https://github.com/mongodb/django-mongodb-backend
- https://www.mongodb.com/blog/post/mongodb-django-backend-now-available-public-preview
👍131
Останній місяць писав дуже багато документації із Sphinx, у форматі reStructuredText. Це формат придуманий у екосистемі пайтона - на ньому написана уся пайтонівська документація, це основна мова розмітки для описів пакетів у PyPi і т.д.
Головний, як то кажуть, selling point, цієї розмітки у тому що невідрендерений документ, себто у сирому вигляді, має добре парситись оком. Саме тому у ньому заголовки зроблені через підкреслення, тайтл лінки можні відділяти від самої лінки і тд.

Чи то через сам Sphinx, чи то через ергономічність reST, але я прям кайфую коли пишу документацію у цьому форматі, чи то через процес чи через результат. І ось коли писав чергову сторінку і пішов подивитись у Cheat Sheet, зрозумів що хотілось би якоїсь інтерактивної доки для reST, інтерактивної по типу https://pythontutor.com/, або https://mypy-play.net/. Щоб можна було потикати приклади прям у браузері і одразу бачити результат. Але нажаль окрім офф доки нічого більш не знайшов. Та коли це нас стримувало - тож я зафігачив свій туторіал, який працює без бекенда - повністю у браузері, ще й "на решту" зробив плейграунд, із можливістю шерінгу (вийшло щось типу pastebin).

Працювати без бекенду воно може завдяки PyScript - це штука котра через pyodide вміє ранити пайтон у браузері і надає апі для маніпулювання DOM-деревом. Трошки заморочившись можна навіть обійтись без CDN і зробити цю штуку офлайновою (у моєму випадку - не залежити від CDN а роздавати усе що треба для туторіала із свого сервера). Для цього щоправда треба трошки поприсідати, бо всі файли треба витягувати вручну із встановлених npm пакетів, але завдяки докеру це можна зробити досить просто: docker run --rm -it -v $(pwd):/code -w /code node bash.

Тож щоб запускати пайтон скрипти у браузері треба підключити у html файлі бандл пайскріпта (взагалі CDN, але у моєму випадку файлики які я сам роздаю)


<script type="module" src="/pyscript/core.js"></script>
<link rel="stylesheet" href="/pyscript/core.css">

<script type="py" src="./main.py" config="./pyscript.toml"></script>


pyscript.toml виглядає так:


name = "reStructuredText Tutorial"
description = "RST tutorial app"
# так як я хочу роздавати бандл пайскрипту сам - прописую шлях до нього
interpreter = "/pyodide/pyodide.mjs"
# ці пакети PyScript сам витягне із інтернету при старті, але іх можна роздавати
# і самому, щоб взагалі не залежити від зовнішніх ресурсів
packages = ["docutils", "pygments", "lzma"]


У html можна навішувати івенти через атрибути, <textarea py-input="_render_rst_from_input_debounced"></textarea>, де _render_rst_from_input_debounced це назва функції у main.py

Спочатку я зробив кожен урок туторіала окремою сторінкою, на яку мав навігувати браузер сам, але інтерпретатор стартує не миттєво і ця затримка при перемиканні між вправами дуже відчувається.
Тож прийшлось зробити SPA на мінімалках - PyScript разом із Pyodide завантажується один раз, а навігація відбувається вже самою апкою через підміну частин сторінки і відсдідковування івента "popstate".

Із кнопкою "Share" у плейграунді вийшло прикольно - можна ділитись документом, але сам документ мені ніде зберігати не потрібно - текст написаний у полі вводу стискається, пакується у base64 і вставляється у URL, тож посилання збергіє у собі весь текст і навіть якщо цей сервіс раптом буде недоступний - маючи посилання можна із нього дістати текст вручну. Приклад посилання:
https://rst-tutorial.yakimka.me/playground?paste=_Td6WFoAAATm1rRGAgAhARYAAAB0L-Wj4ABNAD5dAB7r_UTECOiaAZNIfAWoaP1gjlgAhbSC1dTSjED1rIQXc6T3aTSyiu8C_wll5dYjrwFJZQEcq5rmMFbwrvwAAAAA5PjAT436nmgAAVpOYmy28R-2830BAAAAAARZWg%3D%3D

Прикольна технологія, звісно для "заміни js у браузері" воно так собі підходить, а от робити якісь штуки яким треба пайтонівська ліба, аналогів якої немає у npm - саме те (цікаво, чи можна запустити веб сервер у браузері? 😁)

Лінки:
- https://rst-tutorial.yakimka.me/
- https://rst-tutorial.yakimka.me/playground
- https://www.sphinx-doc.org/en/master/
- https://docutils.sourceforge.io/docs/index.html
- https://pyscript.net/
- https://docs.pyscript.net/2025.3.1/user-guide/offline/
🔥10👍8💊3
Microsoft скасувала фінансування проєкта Faster CPython і звільнила частину команди (як я зрозумів, тих кого не звільнили - розподілять по іншим проєтам). Причому лист про звільнення надіслали коли команда була на пів-шляху до PyCon Pittsburg.
🫠😥
😢15🤬1🌚1
import __hello__
Microsoft скасувала фінансування проєкта Faster CPython і звільнила частину команди (як я зрозумів, тих кого не звільнили - розподілять по іншим проєтам). Причому лист про звільнення надіслали коли команда була на пів-шляху до PyCon Pittsburg. 🫠😥
Щось про це Гвідо мовчить, але він репостнув ось що: у липні вийде документалка про Python 🐍

The full film features: Barry Warsaw, Brett Cannon, @drewhouston, @gvanrossum, @gutworth, @jessicamckellar, Lambert Meertens, Lisa Guo, Lisa Roach, @mariatta, @mitsuhiko, @myriadicity, Robin Friedrich, Robert Kahn, @paulweveritt, @pwang, Sjoerd Mullender, @stevenpemberton, @timoreilly, @teoliphant, @tonroosendaal


У оригінальному твіті перелічено багато людей, причому судячи по нявності там Armin Ronacher (mitsuhiko) - фільм стосується не лише core-python розробників. Ну щож, треба буде подивитись (шкода що у кінотеатрах не покажуть 😁).

https://fxtwitter.com/gvanrossum/status/1924092904932282569
🔥32😁1🤡1
Внутрішні інструменти Google та їх альтернативи
В Google є величезна кількість внутрішних технологій та інструментів. Й є чудовий репозиторій з альтернативними інструментами та технологіями для/від колишніх гуглерів. Не для всього є альтернативи, але можна побачити різноманіття того, що застосовується всередені Google. Якщо цікаво ознайомитися, то ось лінк - https://github.com/jhuangtw/xg2xg
👍7🤔1👀1
Штука котра вартувала мені не однієї години дебагу.
У starlette є два типи мідлварів - BaseHTTPMiddleware та Pure ASGI Middleware. Я хз навіщо аж два, тим паче що "чисту" мідлварь писати не надто складніше ніж іншу.
Але у BaseHTTPMiddleware є особливість, на яку любʼязно вказує документація:
Using BaseHTTPMiddleware will prevent changes to contextvars.ContextVars from propagating upwards.

Тобто якщо ви проставите значення у контекстварі усередині ендпоінта, то усередні мідлварі ви це значення вже не побачите.
Здається звʼязане це із тим що у цьому випадку starlette копіює контекст та пропагує його у ендпоінти, але так як це копія - зміни зроблені у ньому не будуть відображатись у оригіналі.
Але ок, документація вказує що Pure ASGI Middleware не має цієї особливості.
To overcome these limitations, use pure ASGI middleware, as shown below.

Тож ок, мені треба реквесто-специфічний контекст, я для цього роблю свою "чисту" мідлварь, імплементую у ній що треба і все ок, так?
А от і ні, як виявляється, BaseHTTPMiddleware (тварюка така) не лише факапить контекст для себе, а вона ще й факапить контекст навіть для "чистих" мідлварей, якщо BaseHTTPMiddleware вказана першою.

Тобто отак наша мідлварь у якій ми використовуємо contextvars буде робити

app = Starlette()
app.add_middleware(PureMiddleware) # Pure ASGI Middleware який використовує contextvars
app.add_middleware(BaseMiddleware)


А отак вже не буде

app = Starlette()
app.add_middleware(BaseMiddleware)
app.add_middleware(PureMiddleware)


І в принципі до цього можна б було і своєю головою додуматись, бо по класиці мідлварі обгортають одна одну і та що зверху може афектити нижні.
Але дока це явно не пише, і до того ж ти явно можеш і не побачити що у тебе використовується мідлварь якщо юзаєш 3rd-party інтеграції (що зі мною і сталось)
Ось наприклад https://github.com/bobbui/json-logging-python використовує чогось саме BaseHTTPMiddleware.
Коротше якщо вам у starlette (і у fastapi, і подібних фреймворках) треба мідлварь котра використовує contextvars - ставте її завжди першою, бо однієї лише наявності
Pure ASGI Middleware, як виявилось, недостатньо

У першому коменті напишу приклад, як воно працює насправді.


Лінки:
- https://www.starlette.io/middleware/#basehttpmiddleware
- https://www.starlette.io/middleware/#pure-asgi-middleware
👍84
😁9🗿52🤡1💯1
​​Обожнюю таке. Нещодавно вийшла стаття, яка розглядає вплив ChatGPT на змогу людського мозоку розвиватися. Стаття, безумовно, цікава, повна пояснень та висновків, та досить велика. А ще доволі клікбейтна, бо там може бути написано, що люди тупішають, а може навпаки, що використання ChatGPT може допомогти розвивати мозок. Короче, ніпанятна, треба читати.

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

А потім виявилось, що у статтю був вбудований промт інджекшн, який казав, що для LLM треба подавати статтю однобоко, з позиції, що люди тупішають. І журналісти це зробили, бо ж клікбейт. Ну й тому що вони не читали статтю. Отупішали, короче, і журналісти і читачів трошки також.
😁18🤡3
Вже давно хочеться щось по вечорам попілити, але придумувати новий пет проєкт щоб потім його не дороблювати не хочеться, а до Advent of Code ще цілий місяць. Добре що я згадав що є така штука як codecrafters.io
Це не просто якісь абстрактні завдання типу літкода чи туду листів, це платформа яка пропонує робити завдання "а давай відтворимо redis|kafka|git|etc. на мові яка тобі подобається".
Наприклад відтворюємо Redis - там десь близько 90 завдань, для кожного є набір тесткейсів і ти шаг за шагом робиш свій редіс, попутньо розбираючись у тому як все працює у справжньому редісі, у протоколі RESP і тд.
А якщо обрати мову яку ти не знаєш, то окрім розуміння того як працює технологія ще й нову мову вивчиш 😁.
Коротше прикольна ідея, кому також інколи хочеться щось покодити але не хочеться видумувати проєкт, пропрацьовувати задачі і писати тести, а просто хочеться кодити - можете звернути увагу

Можливо комусь буде здаватись що це реклама, але це не реклама. Камон, у мене канал на 250 підписників у який я щось пощу раз на пів-року 😁
🔥161😁1👀1
Цього року (і кожного наступного) AOC буде тривати 12 днів замість 25 (прям як пивні адвент календарі) і більше не буде глобального лідерборда.

Зникнення лідерборда мене не хвилює, бо я у ньому не приймав участі, бо люблю поспати 😁
А 12 днів мабуть буде навіть краще, менше стресу що не встигнеш закінчити івент до кінця року. Взагалі не розумію як автор АОС протримався так довго і скільки взагалі сил і вільного часу було покладено на цей івент за 10 років.
👍14🤯4🤔1
😁16💯2🤪2
Вийшла 9 версія pytest, і тепер у ньому з’явилась повноцінна підтримка subtests.
Цю фічу вони підрізали у стдлібного unittest. Але навіщо, якщо у pytest є такий зручний маркер parametrize?
Бо parametrize корисний лише коли дані для теста відомі ще до того як тест почався, якщо ж щоб отримати ці дані треба спочатку зробити виклик у апі, чи у БД, то зробити це через paramtrize не вийде.
Я часто на ці обмеження натикався і або тягнув якийсь сторонній плагін який реалізовував схожу функціональність, або, що частіше, просто доводилось писати декілька однотипних тестів.

Приклад:


def test_math(subtests):
for a, b, result in [(1, 2, 3), (2, 2, 4), (5, 5, 11)]:
with subtests.test(msg=f"{a}+{b}"):
assert a + b == result


Тепер якщо один підкейс падає — весь тест не валиться, а репорт покаже всі помилки окремо.
Приклад у цьому виді безглуздий, бо саме тут краще зробити як і раніш:


import pytest

@pytest.mark.parametrize(
"a, b, result",
[
(1, 2, 3),
(2, 2, 4),
(5, 5, 11),
]
)
def test_math(a, b, result):
assert a + b == result


Але якщо для отримання значень a, b або result треба робити якісь обчислення, котрі неможливо виконати до початку теста - тоді subtests стане дуже в нагоді.

Лінки:
- https://docs.pytest.org/en/stable/how-to/subtests.html
- https://github.com/pytest-dev/pytest/issues/1367
- https://docs.pytest.org/en/stable/example/parametrize.html
- https://docs.python.org/3.4/library/unittest.html#distinguishing-test-iterations-using-subtests
👍82🥱1
Ну шо, поїхали

https://adventofcode.com/2025/day/1
🔥102
import __hello__
Ну шо, поїхали https://adventofcode.com/2025/day/1
Хто застряг на 2 дні - ось підказка
😁5🤯21🤓1