Гизила.Блог
31 subscribers
4 photos
1 file
21 links
Download Telegram
to view and join the conversation
Коли вчився в університеті, то в нас була лабораторна робота, де потрібно було реалізувувати на C власну реалізацію float по стандарту IEEE 754. Власне в цьому нічого складного немає і, вважаю, це досить корисним заняттям в рамках університетського курсу. Але попри те, що непогано розібрався як це працює, через декілька років забув майже все. В голові навіть не залишилось навіть інформації про загальні властивості float-ів.

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

Скоріше за все за місяць я забуду про те, як влаштований float (в будь-якому випадку, це гуглиться дуже швидко). Але точно впевнений, що відкладеться в пам'яті приклад, як легко можна пояснювати складні речі проситими словами.
На днях спробував у власному проекті замінити Celery на Dramatiq і зіткнувся з проблемою, що не знаю, які залежності були додані у requirements.txt лише для роботи Celery. Тут я подумав, що зараз саме час спробувати використати requirements.in. Цю штуку я вперше побачив у крутих чуваків на відкритих пітонячих проектах, проте досі ніколи не було можливості спробувати. Працює це так: треба створити файл лише з основними залежностями у проекті, далі цей файл потрібно перетворити у requirements.txt з повним списком залежностей. Всі наступні зміни потрібно робити у першому файлі і генерувати requirements.txt. Зараз, наскільки мені відомо, лише pip-compile з pip-tools вміє опрацьовувати requirements.in, хоча цього більш ніж достатньо, бо інструмент доволі активно розвивається.

Власне, моє особисте враження від використання цього інструменту дуже позитивне. Як розробник я працюю лише з основними залежностями, а всю іншу роботу віддаю роботам 🤖
🤟 Нарешті знайшов час, щоб розібратися, як реєструвати безкоштовні домени для власних проктів. В інтернеті бачив купу статтей, які завжди посилалися на freenom.com — реєстратора безкоштовних TLD. Проте коли переходив на цей сайт і вводив назву для домену, то викидало сторінку з запронованими доменами, але не було кнопки, щоб оформити обраний домен.
Покопавшись в інтернетах, я знайшов відео, де автор показував, що потрібно вводити в поле пошуку не приставку для домену, а сам домем з TLD (ml, tk, ga, cf, gq). Для прикладу, замість hyzyla, треба було писати hyzyla.tk
Гизила.Блог
Тиждень тому я писав про те, що планую налаштувати автоматичний деплой мого бота з нуля, написавши власні скрипти на голій Ubuntu. Як я й підозрював, зробити це не складно, але вимагає багато ручних дій і у всіх них можна легко зробити помилку. Тому відразу…
На минулих вихідних спробував запуситити власний проект на DigitalOcean, використовуючи Dokku, що не платити Heroku в районі 20$ за дуже простий проект. І тепер я точно рекомендую Dokku, якщо хочеться запусити щось невелике і не розбиратися як налаштовувати інфраструктуру.

Щоб запустити проект, я купив дроплет на DO за 5$ і виконав декілька команд по офіційний документації, щоб створити проект і додати базу/редіс. Також локально в git додав новий remote зі шляхом на мій проект, щоб можна було деплоїти через команду:

git push dokku master

Для типових ресурсів написані офіційні плагіни, щоб їх можна було теж легко додати до проекту. Для прикладу, щоб додати postgresql мені потрібно було виконати таку команду:

dokku postgres:create my-app

Самі ж налаштування як запустити проект у мене підтягнулися з Procfile, який я писав для Heroku, тому тут я нічого й не робив. Хоча й сам файл не дуже складний:

release: flask db upgrade
web: gunicorn app:app
worker: dramatiq app.tasks

Але прикро одне, що після того як запустився за 5$ на DigitalOcean, я знайшов, що в AWS є подібний сервіс Amazon Lightsail. Тут пропонують створити віртуальну машину за 3.5$, хоча і трохи слабішу.
Цілу годину сьогодні провів, щоб нормально з'єднати Flask і Next.JS для локальної розробки. Flask був на 5000 порту, Next.JS на 3000. На бекенді роблю редирект на фронтендову сторінку, треба абсолютний шлях localhost:3000, щоб перекинуло на фронт. З фронта роблю запити на бекенд — треба абсолютний шлях localhost:5000 і ще й браузер говорить, що не дозволить Cross origin request. Вирішив захордкодити для dev середовища абсолютні шляхи при редіректах і запитах; також на бекенді добавив CORS на всі адреси. Працює, але на душі не комфортно, що рішення є насправді канічним костилем. Тому хочу зробити маленьку утиліту reverse proxy для локальної розробки (або ж знайти, якщо така вже є) і обгорнути в docker контейнер, щоб все це можна було використати через docker-compose. В моїй фантазії це виглядає так:

~ cat proxy.yml
api:
port: 5000
paths:
/api/*: localhost:5000
/* localhost:3000

~ cat docker-compose.yaml
services:
proxy:
image: dev-proxy
por
ts:
- 5000:5000
volumes:
- ./.proxy.yml:/proxy.yml
А з хорошого за сьогодні — знайшов сервіс serveo.net, аналог ngrok. Serveo припав до душі більше ніж ngrok через дві причини:
1) можна зарезерувавати піддомен
2) не треба нічого встановлювати, окрім ssh клієнта, який і так у багатьох є.

Але є одне але — сервіс частенько буває недоступний (як зараз, для прикладу), тому якщо потрібна стабільність, то треба на власній інфраструктурі хостити цей сервіс.

Якщо коротко, то такі інструменти потрібні, щоб ваш сервіс на локальній машині став доступний за справжнім доменом з https. Для прикладу, маю локально веб сервер на 5000 порту, виконую таку команду:

ssh -R hyzyladevserver:80:localhost:5000 serveo.net

і тепер можу знайти мій сервер за такою адресою:
https://hyzyladevserver.serveo.net
Гизила.Блог
Цілу годину сьогодні провів, щоб нормально з'єднати Flask і Next.JS для локальної розробки. Flask був на 5000 порту, Next.JS на 3000. На бекенді роблю редирект на фронтендову сторінку, треба абсолютний шлях localhost:3000, щоб перекинуло на фронт. З фронта…
Нарешті вирішив цю проблему і головне не прийшлося писати нічого свого. Знайшов пару туторіалів, де люди для локальної розробки просто налаштовували nginx і залежності від шляху перекидували на потрібний порт. Власне я лише запхнув це все у docker-compose і написав під власний проект конфіг. Як бонус налаштував https сертифікати для локальної розробки. Тепер у мене і фронт і бек працює разом за єдиною адресою https://localhost.dev/
Гизила.Блог
На минулих вихідних спробував запуситити власний проект на DigitalOcean, використовуючи Dokku, що не платити Heroku в районі 20$ за дуже простий проект. І тепер я точно рекомендую Dokku, якщо хочеться запусити щось невелике і не розбиратися як налаштовувати…
Недавно писав про dokku, інструмент, щоб легко запусити власні веб проекти. Тоді я запускав веб сайт написаний на Flask, HTML генерувася на сервері через шаблони. І мені тоді здавалося, що краще dokku важко, щось придумати. Але на цьому тижні спробував запустити проект з двох частин: Flask для бекенду і Next.js для server side рендерингу HTML. Найбільше не хотілося мати проблем з CORS, піддоменами, абсолютними редиректами і ось цим всім, тому запланував використати досить поширену практику — Nginx буде приймати весь трафік на один домент і за шляхом запиту буде прокидати його на потрібний бекенд. В моєму випадку мені потрібно було перекидати трафік запитів зі шляхом /api/ на Flask, а все інше на Next.js. От тут я й зіткнувся з проблемами, бо в dokku немає стандартних команд, щоб зробити, щось подібне. А серед плагінів я знайшов лише один, який вже 4 роки не підтримується (як буде натхнення, то спробую створити копію і оновити). Витративши купу часу на це, я зробив костиль, де просто перезаписав дефолтний Nginx конфіг на власний 🤷

Мораль одна — немає нічого ідеального
Сьогодні спробував використати XSD схеми для валідації XML і я залишився дуже задоволений. За допомогою схеми декларативно описуєш як має виглядати XML, віддаєш XML зі схемою в бібліотеку для валідації і на виході отримуєш гарантію, що дані мають потрібну тобі форму або ж список детальних помилок, що і де не так. Правда є відчуття, що я ще не зіткнувся зі складними випадками, де схеми не підійдуть. Але для більшості проектів, де структура XML строго задана, це must have інструмент, щоб не писати валідатор XML вашою мовою програмування 🐍.

Поки що помітив лише один мінус — в інтернеті, якісь страшні і доісторичні туторіали про ці схеми. Таке враження, що весь світ перестав користуватися XML.
Шукаю заміну Graphene для створення GraphQL API, тому буду розповідати про різні бібліотеки, які я вважаю перспективними для цих цілей.

Одна з таких бібліотек це ariadne

Плюси:
- всі резолвери є звичайними функціями, які приймають лише два аргументи. В Graphene треба було успадковуватися від класу ObjectType, позначати які поля має об'єкт і сам резовлер писати як метод класу з префіксом resolve_. Для прикладу в Graphene визначення резолвера виглядає так:
class Query(ObjectType):
books = List(Book)

def resolve_boks(root, info, name):
return []


В ariadne
query = QueryType()

@query.field("books")
def get_books(*_):
return []


- має систему розширення і middleware. По правді в Graphene можна було теж додавати middleware, але це було настільки не зручно, що за весь час прийшлося бачити лише один middleware і жодного розширення. Хоча тут довіряю лише обіцянкам розробникам ariadne:
> Open: Ariadne was designed to be modular and open for customization. If you are missing or unhappy with something, extend or easily swap with your own.

- непогана документація, особливо, порівнюючи з документацією в Graphene.

Але й має недоліки. Найжирнішим з них є те що, поки не зрозуміло як розв'язувати проблему N+1 в GraphQL.

Також суб'єктивним мінусом можна вважати, те що ariadne побудований поверх бібліотеки graphql-core (як і Graphene), яка є портованою JS бібліотекою GraphQL.js. В цій бібліотеці навіть проміси з колбек системою портовані з JS. І власне через це дебажити, що відувається під капотом ціє бібліотеки це ще те задоволення.

Пізніше напишу про strawberry і tartiflette
Гизила.Блог
Шукаю заміну Graphene для створення GraphQL API, тому буду розповідати про різні бібліотеки, які я вважаю перспективними для цих цілей. Одна з таких бібліотек це ariadne Плюси: - всі резолвери є звичайними функціями, які приймають лише два аргументи. В Graphene…
Strawberry - це ще одна бібліотека для стоврення GraphQL серверу на Python і мій особистий фаворит серед інших бібліотек. Схема графа задається через анотації типів, дуже схоже на визначення namedtuple чи dataclass в Python. Приклад з документації:

@strawberry.type
class User:
name: str
age: int

@strawberry.type
class Query:
@strawberry.field
def user(self, info) -> User:
return User(name="Patrick", age=100)

schema = strawberry.Schema(query=Query)

З додаткових переваг бібліотеки є плагін для mypy, вбудований функціонал пагінації, завантаження файлів, автентифікація і тд.

Суттєвими недоліками бібліотеки є проблема N+1 запиту і досить бідна документація.

По при деякі недоліки бібліотека дуже мило і перспективно виглядає, тому я віддаю їй 5 з 5 полуниць 🍓🍓🍓🍓🍓 і спробую якось посприяти її розвитку через спонсорство чи розробку. Приклад реального проекту з використанням strawberry можна найти тут.
pytest просто ❤️. Я зробив помилку в назві декоратора @pytest.mark.parameterize, а він підказав мені, що я дурінь і одрукувався:

E   _pytest.mark.MarkerError: 
test_update_document_info has 'parameterize',
spelling should be 'parametrize'

P.S. найшов забавний плагін для pytest pytest-parawtf, який взагалі приймає будь-яке написання цього декоратора:
> Ever wondered how pytest decides to spell parametrise? Was it parameterize? Parametrise? Parametrize? Confused yet? Stop worrying, install this plugin and all variants are valid.
Випадково натрапив на react-pdf — інструмент для генерації PDF з використанням React. Насправді легко можна знайти подібні бібліотеки для генерації PDF під різні мови чи платформи і нічого особливого в цьому немає. Для прикладу для Python є WeasyPrint чи ReportLab. Але react-pdf має одну кілер фічу, через яку варто розказати про нього — PDF може генеруватися як у браузері, так і на сервері. Причому весь прорахунок стилей робить layout engine yoga, який підтримує досить велику підмножину сучасного CSS.

З мого досвіду, коли треба на сервері зберегти щось в PDF, щось що вже рендериться в браузері, то часто піднімають повноцінний браузер на сервері і зберігають сторінку через друк в PDF 😔. А тут можна використовувати один і то й же код і на сервері, і в браузері. Ще не вистачає додаткового режиму рендерингу, де React код перетворювався б у HTML, замість PDF. Це могло б пришвидшити відображення у браузері, а коли потрібно зберегти у PDF, то міняй режим режим рендерингу і зберігай, де завгодно. Тобі було б взагалі ідеально.
Маю ідеальний план вічного заробітку для ІТ-аутсорсу: держава створює тендер на розробку нової системи, бізнес подає заявку з мінімальною ціною для виграшу в тендері (навіть, якщо ця сума не покриє половини витрат). Після перемоги в тендері, компанія розробляє систему згідно з правилами. Але робить API для цієї системи настільки незручним, заплутаним і жахливим, що пару програмістів по ходу розробки звільняються з цієї компанії. Звісно ж не забути написати документацію без прикладів і пояснень.

Далі сісти і чекати, поки до тебе прийдуть компанії за платною консультацією, з приводу інтеграції до цієї системи.

Якщо ви не вмієте писати жахливий API, то можете звернутися до мене за платною консультацією, я покажу приклади в реальному житті і ще підкину пару хитрих ідей 🙃
На днях стало цікаво як на практиці реалізовують безшовний вхід у декілька сервісів за допомогою одного логіна. В теорії я знав, що круті компанії, по типу Google чи Facebook, для цього використовують стандарт OAuth 2.0. Але проблема в тому, що стандарт містить багато деталей, щоб писати реалізацію самостійно з нуля. Тому пішов шукати готові рішення, щоб нічого не писати, але так щоб ні за що й не платити.

Для Python знайшов бібліотеку authlib, в якій є все що потрібно, щоб зробити власні OAuth 1.0/2.0 сервери (зробити вхід під одним логіном у декілька сервісів) або ж підключатися до сторонніх OAuth серверів (вхід за допомогою Facebook чи Twitter). А ще в цій бібліотеці є інтеграція з популярними веб фреймворками Flask, Django, Starlette і FastAPI. (aiohttp немає 😢). Хоча би за це варто зайти до них на github і вліпити їм зірочку.

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

В цілому хочеться спробувати на практиці, запустити OAuth2 сервер. набити пару шишок, що зрозуміти чи легше писати кожного разу свою автентифікацію чи запустити якийсь опенсорсний сервіс чи взагалі може легше і дешевше заплатити якомусь хмарному провайдеру.
Вже майже рік чекаю поки Safari добавить пітримку gap для flexbox, бо хочеться в одному місці написати відступ і навіть не чіпати стилі дочірніх елементів:
.flex-container {
display: flex;
gap: 10px;
}

замість славнозівсного:
.flex-container {
display: flex;
margin: -5px;
}

.flex-wrapper {
margin: 5px;
}


Зарза за даними з caniuse.com лише 70% користувачів мають браузер з підтримкою gap 😔 і поки основний блокер це Safari в яких ще близько 16% ринку бразуерів.
Для мене кожен раз є відкриттям, що в python тип Decimal опрацьовує float і str по різному
Недавно дізнався, що в AWS S3 є безкоштовний і простий спосіб зекономити гроші. Для зберігання даних пропонується 4 різні класи сховищ, кожен з яких повільніший для зчитування даних і відповідно дешевший за попередній клас. Для прикладу на стандартному класі треба заплатити $0.0245 за гігабайт, той же час наступний клас сховища пропонує $0.0135$ за гігабайт і затримка на доступ до файлу в межах 1мс.

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