This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
язык_программирования_python [2025/06/12 05:46] val [FastAPI Uvicorn] |
язык_программирования_python [2025/07/08 09:53] (current) val |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Язык программирования Python ====== | ====== Язык программирования Python ====== | ||
- | * [[https://habr.com/ru/articles/750312/|Python декораторы на максималках. Универсальный рецепт по написанию и аннотированию от мала до велика]] | + | * [[https://habr.com/ru/articles/277679/|Пишем shell скрипты на Python и можно ли заменить им Bash]] |
===== Виртуальная среда Python ===== | ===== Виртуальная среда Python ===== | ||
* [[https://blog.sedicomm.com/2021/06/29/chto-takoe-venv-i-virtualenv-v-python-i-kak-ih-ispolzovat/|Что такое venv и virtualenv в Python, и как их использовать]] | * [[https://blog.sedicomm.com/2021/06/29/chto-takoe-venv-i-virtualenv-v-python-i-kak-ih-ispolzovat/|Что такое venv и virtualenv в Python, и как их использовать]] | ||
- | * [[https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/|https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/]] | + | * [[https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/|Install packages in a virtual environment using pip and venv]] |
* [[https://habr.com/ru/articles/593529/|Poetry — прекрасная альтернатива pip (шпаргалка)]] | * [[https://habr.com/ru/articles/593529/|Poetry — прекрасная альтернатива pip (шпаргалка)]] | ||
+ | * [[https://habr.com/ru/articles/828016/|UV. Обзор пакетного менеджера Python]] | ||
<code> | <code> | ||
Line 25: | Line 25: | ||
- | ===== Интерактивная оболочка ===== | + | ===== Интерактивная оболочка REPL (Read-Eval-Print Loop) ===== |
+ | |||
+ | <code> | ||
+ | (venv1) # python | ||
+ | </code> | ||
+ | |||
+ | * [[https://ru.wikipedia.org/wiki/IPython]] | ||
<code> | <code> | ||
(venv1) # pip install ipython | (venv1) # pip install ipython | ||
</code> | </code> | ||
+ | |||
+ | * [[https://jupyter.org/try-jupyter/notebooks/?path=notebooks/Intro.ipynb|try-jupyter/notebooks]] | ||
+ | * [[https://matplotlib.org/stable/tutorials/pyplot.html|Pyplot tutorial]] | ||
===== Web приложение ===== | ===== Web приложение ===== | ||
Line 36: | Line 46: | ||
* [[#Виртуальная среда Python]] | * [[#Виртуальная среда Python]] | ||
+ | |||
+ | * [[https://habr.com/ru/articles/750312/|Python декораторы на максималках. Универсальный рецепт по написанию и аннотированию от мала до велика]] | ||
* [[https://www.workroom-productions.com/serving-a-directory-with-flask/|Publishing a Directory with Flask]] | * [[https://www.workroom-productions.com/serving-a-directory-with-flask/|Publishing a Directory with Flask]] | ||
Line 116: | Line 128: | ||
server# ###docker run -ti --rm --name pywebd2 python:3.11-alpine sh | server# ###docker run -ti --rm --name pywebd2 python:3.11-alpine sh | ||
- | / # pip install poetry | + | / # ### pip install poetry |
+ | |||
+ | server# apt install python3-poetry; export PYTHON_KEYRING_BACKEND=keyring.backends.null.Keyring #https://stackoverflow.com/questions/74438817/poetry-failed-to-unlock-the-collection | ||
/ # poetry new pywebd2 | / # poetry new pywebd2 | ||
Line 122: | Line 136: | ||
/ # cd pywebd2 | / # cd pywebd2 | ||
- | /pywebd2 # poetry add fastapi dotenv uvicorn | + | /pywebd2 # poetry add fastapi dotenv uvicorn ###gunicorn |
/pywebd2 # more pyproject.toml | /pywebd2 # more pyproject.toml | ||
Line 131: | Line 145: | ||
from dotenv import load_dotenv | from dotenv import load_dotenv | ||
import os | import os | ||
+ | |||
+ | CONST_VER = "ver1.1" | ||
+ | hostname = os.uname().nodename | ||
load_dotenv() | load_dotenv() | ||
Line 138: | Line 155: | ||
@app.get("/") | @app.get("/") | ||
async def home(): | async def home(): | ||
- | return {"data": pywebd_message} | + | return {"data": f"{pywebd_message} from {hostname} app {CONST_VER}"} |
- | | + | |
if __name__ == "__main__": | if __name__ == "__main__": | ||
import uvicorn | import uvicorn | ||
uvicorn.run(app, host="0.0.0.0", port=8000) | uvicorn.run(app, host="0.0.0.0", port=8000) | ||
</code><code> | </code><code> | ||
- | # cat .env | + | /pywebd2 # cat .env |
</code><code> | </code><code> | ||
PYWEBD_MESSAGE="Hello World!!!" | PYWEBD_MESSAGE="Hello World!!!" | ||
+ | </code> | ||
+ | |||
+ | * [[https://tproger.ru/articles/testiruem-na-python-unittest-i-pytest-instrukcija-dlja-nachinajushhih|Тестируем на Python: unittest и pytest. Инструкция для начинающих]] | ||
+ | |||
+ | * [[https://habr.com/ru/articles/349860/|Регулярные выражения в Python от простого к сложному. Подробности, примеры, картинки, упражнения]] | ||
+ | * [[https://regex101.com/|Online Regular expression tester with syntax highlighting]] | ||
+ | |||
+ | <code> | ||
+ | /pywebd2 # cat tests/test_ver_format.py | ||
</code><code> | </code><code> | ||
- | /pywebd2 # ###export PYWEBD_MESSAGE="Another message" | + | import app, re |
+ | |||
+ | assert re.match(r'^ver\d+\.\d+$', app.CONST_VER),"Incorrect VER format" | ||
+ | </code><code> | ||
+ | /pywebd2 # poetry run python3 -m unittest | ||
+ | |||
+ | /pywebd2 # #export PYWEBD_MESSAGE="Another message" | ||
/pywebd2 # poetry run python3 app.py | /pywebd2 # poetry run python3 app.py | ||
Line 154: | Line 186: | ||
/pywebd2 # poetry run uvicorn app:app --reload --host 0.0.0.0 --port 4080 | /pywebd2 # poetry run uvicorn app:app --reload --host 0.0.0.0 --port 4080 | ||
</code> | </code> | ||
- | ===== CRUD Rest API приложение ===== | + | * [[https://github.com/benoitc/gunicorn/issues/2154|TypeError: __call__() missing 1 required positional argument: 'send']] |
+ | <code> | ||
+ | /pywebd2 # ###poetry run gunicorn app:app --bind 0.0.0.0:6080 -k uvicorn.workers.UvicornWorker | ||
+ | </code> | ||
+ | ===== Zabbix LLD приложение ===== | ||
- | * [[https://dev.to/francescoxx/python-crud-rest-api-using-flask-sqlalchemy-postgres-docker-docker-compose-3kh4|Python CRUD Rest API using Flask, SQLAlchemy, Postgres, Docker, Docker Compose]] | + | * [[https://askubuntu.com/questions/244378/running-python-file-in-terminal|Running Python File in Terminal]] |
+ | * [[https://pythonworld.ru/moduli/modul-subprocess.html|Модуль subprocess]] | ||
+ | |||
+ | * [[https://habr.com/ru/articles/488112/|Понимание итераторов в Python]] | ||
+ | * [[https://www.geeksforgeeks.org/python-find-dictionary-matching-value-in-list/|Find dictionary matching value in list - Python]] | ||
+ | * [[https://docs-python.ru/tutorial/vstroennye-funktsii-interpretatora-python/funktsija-next/|Функция next() в Python, следующий элемент итератора]] | ||
+ | |||
+ | ==== Пример 1 ==== | ||
+ | <code> | ||
+ | gate# apt install python3-xmltodict/stable | ||
+ | |||
+ | gate# cat /etc/zabbix/dhcp-pools.py | ||
+ | </code><code> | ||
+ | #!/usr/bin/env python3 | ||
+ | |||
+ | # Example usage: | ||
+ | # ./dhcp-pools.py | ||
+ | # ./dhcp-pools.py LAN1 defined|used | ||
+ | |||
+ | from sys import argv | ||
+ | import subprocess, xmltodict, json | ||
+ | |||
+ | p = subprocess.Popen("/usr/bin/dhcpd-pools -f x", stdout=subprocess.PIPE, shell=True) | ||
+ | (output, err) = p.communicate() | ||
+ | p_status = p.wait() | ||
+ | |||
+ | o = xmltodict.parse(output) | ||
+ | #print (o) | ||
+ | |||
+ | if len(argv)==1: | ||
+ | r=[] | ||
+ | for i in o['dhcpstatus']['shared-network']: | ||
+ | s={} | ||
+ | s["{#POOLNAME}"]=i['location'] | ||
+ | r.insert(1,s) | ||
+ | print(json.dumps(r)) | ||
+ | else: | ||
+ | LANNAME=argv[1] | ||
+ | USDEF=argv[2] | ||
+ | res = next((sub for sub in o['dhcpstatus']['shared-network'] if sub['location'] == LANNAME), None) | ||
+ | print(res[USDEF]) | ||
+ | </code> | ||
+ | |||
+ | ==== Пример 2 ==== | ||
+ | <code> | ||
+ | # cat /usr/local/bin/asterisk.chansip.discovery.py | ||
+ | </code><code> | ||
+ | #!/usr/bin/env python3 | ||
+ | |||
+ | import subprocess, io, json | ||
+ | |||
+ | result=[] | ||
+ | |||
+ | proc = subprocess.Popen('/usr/sbin/asterisk -x "sip show users" | tail -n +2 | cut -d" " -f1', stdout=subprocess.PIPE, shell=True) | ||
+ | for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"): | ||
+ | #print(line.rstrip()) | ||
+ | s={} | ||
+ | s["{#CHANNAME}"]="SIP/"+line.rstrip() | ||
+ | result.insert(1,s) | ||
+ | print(json.dumps(result)) | ||
+ | </code> | ||
+ | |||
+ | Вариант от DeepSeek | ||
+ | |||
+ | <code> | ||
+ | # cat /usr/local/bin/asterisk.chansip.discovery.ds.py | ||
+ | </code><code> | ||
+ | #!/usr/bin/env python3 | ||
+ | |||
+ | import subprocess | ||
+ | import json | ||
+ | |||
+ | # Запускаем команду и сразу получаем вывод | ||
+ | output = subprocess.check_output( | ||
+ | '/usr/sbin/asterisk -x "sip show users" | tail -n +2 | cut -d" " -f1', | ||
+ | shell=True, | ||
+ | text=True | ||
+ | ) | ||
+ | |||
+ | # Формируем список словарей в одну строку | ||
+ | result = [{"{#CHANNAME}": f"SIP/{line.strip()}"} for line in output.splitlines() if line.strip()] | ||
+ | |||
+ | # Выводим результат в формате JSON | ||
+ | print(json.dumps(result)) | ||
+ | </code> | ||
===== Zabbix API приложение ===== | ===== Zabbix API приложение ===== | ||
Line 236: | Line 356: | ||
</code> | </code> | ||
- | ===== Zabbix LLD приложение ===== | ||
- | * [[https://www.geeksforgeeks.org/python-find-dictionary-matching-value-in-list/]] | + | ===== CRUD Rest API приложение ===== |
- | * [[https://docs-python.ru/tutorial/vstroennye-funktsii-interpretatora-python/funktsija-next/]] | + | |
- | <code> | + | |
- | gate# apt install python3-xmltodict/stable | + | |
- | gate# cat /etc/zabbix/dhcp-pools.py | + | * [[https://dev.to/francescoxx/python-crud-rest-api-using-flask-sqlalchemy-postgres-docker-docker-compose-3kh4|Python CRUD Rest API using Flask, SQLAlchemy, Postgres, Docker, Docker Compose]] |
- | </code><code> | + | |
- | #!/usr/bin/env python3 | + | |
- | + | ||
- | # Example usage: | + | |
- | # ./dhcp-pools.py | + | |
- | # ./dhcp-pools.py LAN1 defined|used | + | |
- | + | ||
- | from sys import argv | + | |
- | import subprocess, xmltodict, json | + | |
- | + | ||
- | p = subprocess.Popen("/usr/bin/dhcpd-pools -f x", stdout=subprocess.PIPE, shell=True) | + | |
- | (output, err) = p.communicate() | + | |
- | p_status = p.wait() | + | |
- | + | ||
- | o = xmltodict.parse(output) | + | |
- | + | ||
- | if len(argv)==1: | + | |
- | r=[] | + | |
- | for i in o['dhcpstatus']['shared-network']: | + | |
- | s={} | + | |
- | s["{#POOLNAME}"]=i['location'] | + | |
- | r.insert(1,s) | + | |
- | print(json.dumps(r)) | + | |
- | else: | + | |
- | LANNAME=argv[1] | + | |
- | USDEF=argv[2] | + | |
- | res = next((sub for sub in o['dhcpstatus']['shared-network'] if sub['location'] == LANNAME), None) | + | |
- | print(res[USDEF]) | + | |
- | </code> | + | |
===== Дополнительные материалы ===== | ===== Дополнительные материалы ===== |