🟣 Потоки вводу/виводу (Input/Output Streams, stdin/stdout/stderr)
Повернемось до теми Корисні речі, які варто знати про процес
У попередньому прикладі коду я використав такий вивід:
Що це значить?
Подивимось у документацію:
🔗 Документація
Простими слова file це те куди виводити рядок нашого повідомлення. По замовченню вивід відбувається у sys.stdout. Також вивід може відбуватись у реальний файл або у поток sys.stdout - спеціальний потік для помилок.
⚠️ Варто зауважити: що потік в/в в анг. варіанті це stream i/o і не варто його плутати з thread - потоком виконання.
sys.stdout як sys.stderr це два потоки для виводу (stream output) обидва виводять текст у консоль користувач не бачить різницю між ними візуально.
При програмній автоматизації процесів можливо перехоплювати текст з обох потоків, можемо окремо мати звичайний тест інформаційного характеру з sys.stdout і окремо з sys.stderr
Є ще третій поток sys.stdin - це поток для вводу, він необхідний для читання вводу користувача у консоль.
При програмній автоматизації ми також можемо вводити текст замість користувача.
👉 Практична цінність знання про потоки в/в полягає саме у можливості автоматизувати взаємодію між процесами (IPC) шляхом їх перехоплення.
Повернемось до теми Корисні речі, які варто знати про процес
У попередньому прикладі коду я використав такий вивід:
print("Usage: python script.py <num1> <num2>", file=sys.stderr)Що це значить?
Подивимось у документацію:
print(*objects, sep=' ', end='\n', file=None, flush=False)
The file argument must be an object with a write(string) method; if it is not present or None,
sys.stdout will be used. Since printed arguments are converted to text strings,
print() cannot be used with binary mode file objects. For these, use file.write(...) instead.
🔗 Документація
Простими слова file це те куди виводити рядок нашого повідомлення. По замовченню вивід відбувається у sys.stdout. Також вивід може відбуватись у реальний файл або у поток sys.stdout - спеціальний потік для помилок.
⚠️ Варто зауважити: що потік в/в в анг. варіанті це stream i/o і не варто його плутати з thread - потоком виконання.
sys.stdout як sys.stderr це два потоки для виводу (stream output) обидва виводять текст у консоль користувач не бачить різницю між ними візуально.
При програмній автоматизації процесів можливо перехоплювати текст з обох потоків, можемо окремо мати звичайний тест інформаційного характеру з sys.stdout і окремо з sys.stderr
Є ще третій поток sys.stdin - це поток для вводу, він необхідний для читання вводу користувача у консоль.
При програмній автоматизації ми також можемо вводити текст замість користувача.
👉 Практична цінність знання про потоки в/в полягає саме у можливості автоматизувати взаємодію між процесами (IPC) шляхом їх перехоплення.
👍1
🟢 Потоки введення/виведення. Практика.
У Python для створення підпроцесів використовується бібліотека subprocess.
Вона дозволяє запускати програми та працювати з їхніми потоками введення/виведення.
subprocess добре підходить для простих випадків з синхронном кодом.
Але цікавіше розглянути асинхронний приклад з asyncio, який працює одразу з усіма трьома потоками введення/виведення.
Ідея проста: запускаємо Python у інтерактивному режимі та виконуємо дві операції — 2+2 і 1/0.
Вивід у консоль:
Як бачимо ми отримали текст окремо stdout і окремо stderr.
Звісно аналогічним чином ми можемо запускати системі утіліти або інші програми написані на інших мовах програмування — це простір для автоматизації.
Але трохи дивно чому python пише текст привітання саме у stderr
У Python для створення підпроцесів використовується бібліотека subprocess.
Вона дозволяє запускати програми та працювати з їхніми потоками введення/виведення.
subprocess добре підходить для простих випадків з синхронном кодом.
Але цікавіше розглянути асинхронний приклад з asyncio, який працює одразу з усіма трьома потоками введення/виведення.
Ідея проста: запускаємо Python у інтерактивному режимі та виконуємо дві операції — 2+2 і 1/0.
import asyncio
import sys
async def read_stream(name: str, stream: asyncio.StreamReader):
while data := await stream.readline():
line = data.decode("utf8").rstrip()
print(f"[{name}]", line)
async def main():
process = await asyncio.create_subprocess_exec(
sys.executable, "-i", # python -i
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout_task = asyncio.create_task(
read_stream("stdout", process.stdout),
)
stderr_task = asyncio.create_task(
read_stream("stderr", process.stderr),
)
process.stdin.write(b"2+2\n")
await process.stdin.drain()
process.stdin.write(b"1/0\n")
await process.stdin.drain()
process.stdin.write(b"exit()\n")
await process.stdin.drain()
await process.wait() # Чекаємо завершення підпроцесу
Вивід у консоль:
[stderr] Python 3.11.6 (tags/v3.11.6:8b6ee5b, Oct 2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)] on win32
[stderr] Type "help", "copyright", "credits" or "license" for more information.
[stdout] 4
[stderr] >>> >>> Traceback (most recent call last):
[stderr] File "<stdin>", line 1, in <module>
[stderr] ZeroDivisionError: division by zero
[stderr] >>>
Як бачимо ми отримали текст окремо stdout і окремо stderr.
Звісно аналогічним чином ми можемо запускати системі утіліти або інші програми написані на інших мовах програмування — це простір для автоматизації.
Python Materials For Beginners
Знову git www.youtube.com/watch?v=y6meVhckYmQ #git
Непогане відео про "Environment variables" та .env файли.
https://www.youtube.com/watch?v=Hn5sgLafAMQ
https://www.youtube.com/watch?v=Hn5sgLafAMQ
YouTube
Your .env File Is Lying to You
This video breaks down env vars from the operating system level up — where they live, how they move between processes, and why your app works locally but breaks in Docker.
Environment variables aren't a framework feature — they're an OS primitive. Every…
Environment variables aren't a framework feature — they're an OS primitive. Every…
🔥1
Цікаве відео про черги повідомлень.
#rabbitmq #kafka
https://www.youtube.com/watch?v=byCvosoavLw&pp=ugUEEgJ1aw%3D%3D
#rabbitmq #kafka
https://www.youtube.com/watch?v=byCvosoavLw&pp=ugUEEgJ1aw%3D%3D
YouTube
Kafka чи RabitMQ - Що обрати?
Kafka та RabbitMQ вирішують різні проблеми, обери неправильно і будеш змушений усе перероблювати. Це відео в деталях розглядає як вони працюють під копотом — RabbitMQ як розумний брокер повідомлень, який виконує маршрутизацію та видаляє повідомлення, Kafka…
Трохи про Rotating Proxy.
(Гадаю ця інформація буде корисна при покупці проксі для скрапінгу даних.)
По режиму керування:
1. Per-request rotation
2. Session-based rotation
3. Automated request management
За типом інфраструктури/провайдера:
1. Residential High reliability Real home IPs
2. Datacenter Fast & cost-efficient Server IPs
3. Mobile Carrier IPs Mobile-network routing
4. ISP Datacenter speed Consumer-ISP routing
#proxy
https://www.youtube.com/watch?v=YTQVusxV-Bs
(Гадаю ця інформація буде корисна при покупці проксі для скрапінгу даних.)
По режиму керування:
1. Per-request rotation
2. Session-based rotation
3. Automated request management
За типом інфраструктури/провайдера:
1. Residential High reliability Real home IPs
2. Datacenter Fast & cost-efficient Server IPs
3. Mobile Carrier IPs Mobile-network routing
4. ISP Datacenter speed Consumer-ISP routing
#proxy
https://www.youtube.com/watch?v=YTQVusxV-Bs
YouTube
What Is a Rotating Proxy? Types, Uses & Setup
Your scraper's running fine, then your success rate tanks and the data stops flowing. Sound familiar? A rotating proxy fixes exactly that.
In this video, Vidas from Oxylabs breaks down how IP rotation actually works under the hood, and why it's the difference…
In this video, Vidas from Oxylabs breaks down how IP rotation actually works under the hood, and why it's the difference…
Як на мене дуже цікаво буде спробувати RAG.
#rag #embedding
https://www.youtube.com/watch?v=QmiaI5HiLmg
#rag #embedding
https://www.youtube.com/watch?v=QmiaI5HiLmg
YouTube
RAG - детально для Початківців (RAG, Embedding, Vector DB)
Сьогодні ми говоримо про RAG, Embeddings та пошук за семантичним співпадінням.
Також ми познайомимось із векторними базами даних.
Підтримати канал:
Patreon: https://patreon.com/python_decoded
Посилання на Банку: https://send.monobank.ua/jar/3CiHEjphUu…
Також ми познайомимось із векторними базами даних.
Підтримати канал:
Patreon: https://patreon.com/python_decoded
Посилання на Банку: https://send.monobank.ua/jar/3CiHEjphUu…
🔥5❤2
Ще одне корисне відео, рекомендую до ознайомлення.
#pydantic
https://www.youtube.com/watch?v=H0Q-o-4ebb4
#pydantic
https://www.youtube.com/watch?v=H0Q-o-4ebb4
YouTube
Pydantic - Просунуті Перевірки та Перетворення Даних.
Продовжуємо знайомитись із бібліотекою Pydantic, і спробуємо дослідити набір спеціалізованих інструментів для створення просунутих перевірок.
- BeforeValidator
- AfterValidator
- PlainValidator
- WrapValidator
- @field_validator
- @model_validator
Підтримати…
- BeforeValidator
- AfterValidator
- PlainValidator
- WrapValidator
- @field_validator
- @model_validator
Підтримати…
🔥2
Підбірка відео по конкурентності:
Асинхронний Пайтон за 5 хвилин / Python - AsyncIO
Введення у Асинхронне Програмування - Процеси, Потоки, GIL та Asyncio
Основи роботи з Процесами та Потоками у Пайтоні
#asyncio
Асинхронний Пайтон за 5 хвилин / Python - AsyncIO
Введення у Асинхронне Програмування - Процеси, Потоки, GIL та Asyncio
Основи роботи з Процесами та Потоками у Пайтоні
#asyncio
YouTube
Асинхронний Пайтон за 5 хвилин / Python - AsyncIO
Чи можливо розібратись в Асинхронному Пайтоні за 5 хвилин?
Дивись це відео, і переконайся в цьому сам, це не займе в тебе багато часу.
Підтримати канал:
Patreon: https://patreon.com/python_decoded
Посилання на Банку: https://send.monobank.ua/jar/3CiHEjphUu…
Дивись це відео, і переконайся в цьому сам, це не займе в тебе багато часу.
Підтримати канал:
Patreon: https://patreon.com/python_decoded
Посилання на Банку: https://send.monobank.ua/jar/3CiHEjphUu…
😭1
Python Materials For Beginners
Підбірка відео по конкурентності: Асинхронний Пайтон за 5 хвилин / Python - AsyncIO Введення у Асинхронне Програмування - Процеси, Потоки, GIL та Asyncio Основи роботи з Процесами та Потоками у Пайтоні #asyncio
На жаль в багатьох відео пояснення асинхронки у python якесь не дуже (у тому числі у відео що я привів вище). Чомусь багато авторів лізуть під капот діставати генератори, які не дуже й то пояснюють основну суть.
На мою думку варто більше акцентувати свою увагу на розумінні IO-bound та CPU-bound задачах.
Також важливі моменти asyncio.gather та asyncio.wait, asyncio.wait_for які як раз дають змогу
отримувати виграш у часі виконання програми за рахунок IO-bound.
#asyncio
На мою думку варто більше акцентувати свою увагу на розумінні IO-bound та CPU-bound задачах.
Також важливі моменти asyncio.gather та asyncio.wait, asyncio.wait_for які як раз дають змогу
отримувати виграш у часі виконання програми за рахунок IO-bound.
#asyncio
I/O-bound задача (Input/Output bound — задача, обмежена вводом-виводом) — це тип задач у програмуванні, під час виконання яких процесор більшість часу простоює в очікуванні, поки завершиться зовнішня операція.
У таких задачах швидкість виконання програми залежить не від потужності процесора (CPU), а від швидкості зовнішніх систем чи пристроїв.
До I/O-bound можна віднести:
1. Роботу з мережею (у тому числі HTTP-запити та роботу з БД).
2. Роботу з пристроями (наприклад, роботу через serial port).
3. Роботу з файлами.
Операційна система надає спеціальний набір функцій для асинхронної роботи, які зазвичай називають неблокуючими (non-blocking). Python будує над ними свою обгортку яка підтримує синтаксис async/await
#asyncio
У таких задачах швидкість виконання програми залежить не від потужності процесора (CPU), а від швидкості зовнішніх систем чи пристроїв.
До I/O-bound можна віднести:
1. Роботу з мережею (у тому числі HTTP-запити та роботу з БД).
2. Роботу з пристроями (наприклад, роботу через serial port).
3. Роботу з файлами.
Операційна система надає спеціальний набір функцій для асинхронної роботи, які зазвичай називають неблокуючими (non-blocking). Python будує над ними свою обгортку яка підтримує синтаксис async/await
#asyncio
Бібліотеки httpx і curl_cffi (на відміну від requests) надають як синхроний так і асинхронний інтерфейси:
За виключенням синтаксису async/await і запуску через
І що варто підкреслити не має виграшу у часі виконання.
Обидва приклади відправляють HTTP запит на сервер, а потім чекають від нього відповіді.
#asyncio
import httpx
def main():
with httpx.Client() as client:
response = client.get("https://httpbin.org/get")
print(response.status_code)
main()
import asyncio
import httpx
async def main():
async with httpx.AsyncClient() as client:
response = await client.get("https://httpbin.org/get")
print(response.status_code)
asyncio.run(main())
За виключенням синтаксису async/await і запуску через
asyncio.run різниці немає.І що варто підкреслити не має виграшу у часі виконання.
Обидва приклади відправляють HTTP запит на сервер, а потім чекають від нього відповіді.
#asyncio
Виграшу у часі виконання.
За рахунок неблокуючих операцій ми можемо відправити запит на сервер, але не чекати відповіді - робити іншу задачу.
#asyncio #create_task
За рахунок неблокуючих операцій ми можемо відправити запит на сервер, але не чекати відповіді - робити іншу задачу.
async with httpx.AsyncClient() as client:
task = asyncio.create_task(
client.get("https://example.com/")
)
# поки запит обробляється, ми
# не чекаємо відповіді, а робимо іншу задачу
# наприклад інший запит або якісь обчислення
# тут пізніше отримуємо відповідь
response = await task
print(response.status_code)
#asyncio #create_task
Виграш у часі виконання за рахунок одночасного очікування відповідей.
Вивід:
API
Якби ми робили запити послідовно, час виконання становив би 1 + 3 + 2 = ~6 с. Проте завдяки асинхронності ми досягли результату ~3,3 с, що співмірне з часом найдовшого запиту.
#asyncio #gather
asyncio.gatherimport time
import asyncio
import httpx
# Ключ від безкоштовного апі https://app.reqres.in
API_KEY = "free_user_****************"
async def main():
async with httpx.AsyncClient() as client:
client.headers["x-api-key"] = API_KEY
start = time.monotonic()
responses = await asyncio.gather(
client.get("https://reqres.in/api/users?delay=1"), # запит 1с
client.get("https://reqres.in/api/users?delay=3"), # запит 3с
client.get("https://reqres.in/api/users?delay=2"), # запит 2с
)
print(f"Elapsed: {time.monotonic() - start:.2f} s")
print("Status codes: ", [r.status_code for r in responses])
if __name__ == "__main__":
asyncio.run(main())
Вивід:
Elapsed: 3.30 s
Status codes: [200, 200, 200]
API
app.reqres.in дозволяє задати час відповіді для кожного запиту (1, 3 та 2 с). Це дає можливість побачити перевагу асинхронності, коли запити виконуються групою й відповіді очікуються одночасно.Якби ми робили запити послідовно, час виконання становив би 1 + 3 + 2 = ~6 с. Проте завдяки асинхронності ми досягли результату ~3,3 с, що співмірне з часом найдовшого запиту.
#asyncio #gather
❤2