mirror of
https://git.digitalstudium.com/digitalstudium/digitalstudium.com
synced 2023-12-29 08:06:35 +00:00
Remove prism
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: "Python: Как легко написать CLI инструмент для Linux с помощью Fire"
|
||||
category: python-lifehacks
|
||||
filename: how-to-easily-write-linux-cli-tool
|
||||
date: 2023-04-09
|
||||
---
|
||||
Хочу поделиться самым простым из известных мне способов написать CLI инструмент для администрирования Linux
|
||||
на Python.
|
||||
## Шаг 1. Установка Fire
|
||||
```bash
|
||||
pip install fire
|
||||
```
|
||||
## Шаг 2. Создаём простейший CLI инструмент
|
||||
Вот пример CLI инструмента, который выводит в терминал версию Linux:
|
||||
<!--more-->
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import fire
|
||||
import platform
|
||||
|
||||
|
||||
class SysInfo:
|
||||
"""A CLI tool for getting system information about Linux server"""
|
||||
|
||||
def kernel(self):
|
||||
"""A method for getting kernel version"""
|
||||
version = platform.release()
|
||||
return f"Kernel version: {version}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
obj = SysInfo()
|
||||
fire.Fire(obj)
|
||||
```
|
||||
Вставьте этот код в файл с именем `my-cli-tool` и дайте права на выполнение:
|
||||
```bash
|
||||
chmod +x my-cli-tool
|
||||
```
|
||||
Затем положите этот файл по пути `/usr/local/bin`:
|
||||
```bash
|
||||
sudo cp ./my-cli-tool /usr/local/bin
|
||||
```
|
||||
|
||||
Чтобы воспользоваться этим инструментом, достаточно набрать команду:
|
||||
```bash
|
||||
my-cli-tool kernel
|
||||
```
|
||||
|
||||
Вы увидите такой вывод:
|
||||
```plaintext
|
||||
❯ my-cli-tool kernel
|
||||
Kernel version: 6.2.2-060202-generic
|
||||
```
|
||||
|
||||
Как видите, достаточно создать класс, метод(ы) в нём, и передать объект класса внутрь функции fire.Fire() - и cli инструмент готов!
|
||||
При этом автоматически сгенерируется help страница, вызвать которую можно с помощью флага `--help`:
|
||||
```bash
|
||||
my-cli-tool --help
|
||||
```
|
||||
Вы получите такой вывод:
|
||||
```plaintext
|
||||
NAME
|
||||
my-cli-tool - A CLI tool for getting system information about Linux server
|
||||
|
||||
SYNOPSIS
|
||||
my-cli-tool COMMAND
|
||||
|
||||
DESCRIPTION
|
||||
A CLI tool for getting system information about Linux server
|
||||
|
||||
COMMANDS
|
||||
COMMAND is one of the following:
|
||||
kernel
|
||||
A method for getting kernel version
|
||||
```
|
||||
|
||||
## Шаг 3. Усложняем инструмент
|
||||
Например, мы хотим также, чтобы наш инструмент мог выводить версию ядра в коротком варианте, то есть так: `6.2.2`.
|
||||
Переписываем код следующим образом:
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
import fire
|
||||
import platform
|
||||
|
||||
|
||||
class SysInfo:
|
||||
"""A CLI tool for getting system information about Linux server"""
|
||||
|
||||
def kernel(self, format: ("short", "full") = "full"):
|
||||
"""A method for getting kernel version"""
|
||||
version = platform.release()
|
||||
if format == "short":
|
||||
return version.split("-")[0]
|
||||
return f"Kernel version: {version}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
obj = SysInfo()
|
||||
fire.Fire(obj)
|
||||
```
|
||||
|
||||
Теперь мы можем набрать такую команду:
|
||||
```bash
|
||||
my-cli-tool kernel --format short
|
||||
```
|
||||
На что должен последовать такой вывод:
|
||||
```plaintext
|
||||
6.2.2
|
||||
```
|
||||
При этом автоматически будет скорректирована help страница, туда будет добавлен флаг `--format` и его возможные значения:
|
||||
```bash
|
||||
my-cli-tool kernel --help
|
||||
```
|
||||
Вывод:
|
||||
```plaintext
|
||||
NAME
|
||||
my-cli-tool kernel - A method for getting kernel version
|
||||
|
||||
SYNOPSIS
|
||||
my-cli-tool kernel <flags>
|
||||
|
||||
DESCRIPTION
|
||||
A method for getting kernel version
|
||||
|
||||
FLAGS
|
||||
-f, --format=FORMAT
|
||||
Type: ('short', 'full')
|
||||
Default: 'full'
|
||||
```
|
||||
|
||||
## Шаг 4. Создаём бинарный файл
|
||||
|
||||
Сначала устанавливаем `pyinstaller`:
|
||||
```bash
|
||||
pip install pytinstaller
|
||||
```
|
||||
Затем запускаем команду:
|
||||
```
|
||||
pyinstaller my-cli-tool --onefile
|
||||
```
|
||||
У вас должна появиться папка `dist`, а в ней файл бинарный `my-cli-tool` со всеми зависимостями, который можно использовать даже на серверах,
|
||||
на которых не установлен python или fire. Просто кладём этот файл по пути `/usr/local/bin` и `my-cli-tool` можно использовать!
|
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: "Python: Как параллельно загрузить несколько веб-страниц"
|
||||
category: python-lifehacks
|
||||
filename: how-to-load-multiple-web-pages-in-parallel-using-python
|
||||
date: 2022-05-15
|
||||
---
|
||||
|
||||
Сначала нужно установить пакет `aiohttp`. Для установки aiohttp выполните команду:
|
||||
```bash
|
||||
pip install aiohttp[speedups]
|
||||
```
|
||||
Суффикс `[speedups]` нужен для установки ускоряющих aiohttp пакетов - `aiodns`, `cchardet`. Затем создайте файл<!--more-->
|
||||
main.py с таким кодом:
|
||||
```python
|
||||
import aiohttp
|
||||
import asyncio
|
||||
import socket
|
||||
|
||||
|
||||
async def fetch_urls(urls):
|
||||
resolver = aiohttp.AsyncResolver()
|
||||
connector = aiohttp.TCPConnector(resolver=resolver, family=socket.AF_INET, use_dns_cache=False)
|
||||
session = aiohttp.ClientSession(connector=connector)
|
||||
|
||||
async def fetch_url(url, session):
|
||||
async with session.get(url) as resp:
|
||||
print(resp.status)
|
||||
print(await resp.text())
|
||||
|
||||
tasks = [fetch_url(url, session) for url in urls]
|
||||
await asyncio.gather(*tasks)
|
||||
await session.close()
|
||||
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
urls = ['http://httpbin.org/get?key=value1', 'http://httpbin.org/get?key=value2', 'http://httpbin.org/get?key=value3']
|
||||
|
||||
loop.run_until_complete(fetch_urls(urls))
|
||||
```
|
||||
Теперь можно запустить созданный файл с помощью команды:
|
||||
```bash
|
||||
python3 main.py
|
||||
```
|
||||
Вы увидите примерно такой вывод:
|
||||
```plaintext
|
||||
200
|
||||
{
|
||||
"args": {
|
||||
"key": "value2"
|
||||
},
|
||||
"headers": {
|
||||
"Accept": "*/*",
|
||||
"Accept-Encoding": "gzip, deflate",
|
||||
...
|
||||
```
|
||||
Все три запроса при этом выполнятся параллельно. Вы можете добавить любые url-ы в список <var>urls</var>, например:
|
||||
```python
|
||||
urls = ['https://yandex.com', 'https://google.com', 'https://yahoo.com']
|
||||
```
|
||||
|
||||
Чтобы выполнить HEAD, POST, PUT, DELETE запросы, просто замените в коде `session.get(url)` на соответствующий
|
||||
метод:
|
||||
|
||||
```python
|
||||
session.post('http://httpbin.org/post', data=b'data')
|
||||
session.put('http://httpbin.org/put', data=b'data')
|
||||
session.delete('http://httpbin.org/delete')
|
||||
session.head('http://httpbin.org/get')
|
||||
session.options('http://httpbin.org/get')
|
||||
session.patch('http://httpbin.org/patch', data=b'data')
|
||||
```
|
Reference in New Issue
Block a user