Syntax highlighting of python

= Python =

<<TableOfContents(2)>>

== Refs ==

[[https://docs.python.org/3/|Python Documentation|class=" moin-https"]]

[[https://docs.python.org/3.10/library/index.html|The Python Standard Library 3.10|class=" moin-https"]]

[[https://docs.python.org/3/library/functions.html|Built-in Functions|class=" moin-https"]]

[[https://docs.python.org/3/library/exceptions.html|Build In Exceptions|class=" moin-https"]]

[[https://docs.python.org/3/py-modindex.html|Python Module Index|class=" moin-https"]]

[[https://www.python.org/dev/peps/pep-0008/#code-lay-out|PEP 8|class=" moin-https"]]

[[https://www.flake8rules.com/|Codestyle Error Index|class=" moin-https"]]

[[https://www.nylas.com/blog/packaging-deploying-python/|How We Deploy Python Code|class=" moin-https"]]

[[https://peps.python.org/pep-0257/|Docstring Conventions|class=" moin-https"]]

[[https://python.hotexamples.com/ru/|Hot Examples|class=" moin-https"]]

[[https://pypi.org/project/mypy/]] - check annotations

== Sections ==

 . [[python/gitignore|gitignore]]
 . ~+[[python/pip|pip]]+~

== Annotations ==

{{{#!highlight python
import datetime
# --- Переменная noon снабжена аннотацией типа datetime.time
noon: datetime.time = datetime.time(12, 0, 0)
# --- Аннотирование аргументов конструктора и возратного значения
def __init__(self, length: int, color: str) -> None:
# --- игнорирование типов для того, чтобы проверочная программа типа mypy не выдавала предупреджения
def removeThreesAndFives(number: int) -> int:
    number = str(number) # type: ignore
    number = number.replace('3', '').replace('5', '') # type: ignore
    return int(number)

# --- переменной spam может быть присвоено значение типа int, str или float
from typing import Union
spam: Union[int, str, float] = 42
spam = 'hello'
spam = 3.14

# --- переменной lastName может быть присвоено str или None
from typing import Optional
lastName: Optional[str] = None
lastName = 'Sweigart'

# --- любое значение переменной
from typing import Any
import datetime
spam: Any = 42
spam = datetime.date.today()
spam = True

# --- переменной может быть присвоен список с любыми значениями
spam: list = [42, 'hello', 3.14, True]
# --- переменной может быть присвоен список с органиченными типами значений
from typing import List, Union
# --- --- только строки
catNames: List[str] = ['Zophie', 'Simon', 'Pooka', 'Theodore']
# --- --- целочисленные или числа с плавающей точкой
numbers: List[Union[int, float]] = [42, 3.14, 99.9, 86]

}}}

== Recipes ==

=== Python3 as Default ===

https://unix.stackexchange.com/a/498264

{{{#!highlight bash
python --version
sudo su
update-alternatives --install /usr/bin/python python /usr/bin/python3 1
exit
python --version

}}}

То же можно выполнить и для `pip3`

=== Upgrade Python ===

https://phoenixnap.com/kb/upgrade-python#ftoc-heading-7

{{{#!highlight bash
sudo apt update
sudo apt install python3.9
python3.9
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 2
sudo update-alternatives --config python3
sudo rm /usr/bin/python3
sudo ln -s python3.9 /usr/bin/python3
python3 --version

}}}

== Interpreter ==

=== Import module ===

{{{#!highlight python
# --- исходный вариант
import string
string
<module 'string' from '/usr/lib/python3.8/string.py'>

# --- вариант 1
exec("import string")
string
<module 'string' from '/usr/lib/python3.8/string.py'>

# --- вариант 2
string = __import__('string')
string
<module 'string' from '/usr/lib/python3.8/string.py'>

}}}

=== Reload module in python ===

{{{#!highlight python
>>> import myscript
>>> ...
>>> from importlib import reload
>>> reload(mysript)

}}}

== Standard Library ==

=== 12. Internet ===

FTP

{{{#!highlight python
import ftplib
ftp = ftplib.FTP(host='ftp.zakupki.gov.ru')
ftp.login(user='free', passwd='free')
ftp.nlst()
ftp.quit()

}}}

=== 16. Developer Tools ===

PDB

{{{#!highlight python
import pdb; pdb.set_trace()

}}}

== Virtual Env ==

=== Poetry ===

[[https://python-poetry.org/]]

[[https://github.com/yhino/pipenv-poetry-migrate]]

Install ([[https://python-poetry.org/docs/]])

{{{#!highlight bash
curl -sSL https://install.python-poetry.org | python3 -

}}}

=== Pipenv ===


[[https://pipenv.pypa.io/en/latest/]]

{{{#!highlight bash
# --- init env
pipenv install
# --- run env
pipenv shell
# --- run command in env
pipenv run
# --- install dev packages
pipenv install --dev pytest

}}}

ВНИМАНИЕ. Если в директории проекта имеется файл ''.env'', то pipenv по умолчанию загрузит его при старте. Следовательно, исправления этого файла после `pipenv shell` не будет отражаться в окружении.
См. https://pipenv-fork.readthedocs.io/en/latest/advanced.html#automatic-loading-of-env

Python Upgrade

 1. Выходим из виртуального окружения (если активно)
 1. Удаляем директорию окружения .local/share/virtualenvs/project-name-xxx. Путь к окружению отображается при активации `pipenv shell`
 1. Корректируем версию python в файле Pipenv
 1. Выполняем `pipenv install` и `pipenv shell`
 1. Проверяем `python --version`

=== Venv ===

Python 3

{{{#!highlight bash
# --- создаем виртуальное окружение
python3 -m virtualenv venv
# --- активируем виртуальное окружение
. venv/bin/activate
# --- деактивируем виртуальное окружение
deactivate

}}}

Python 2

{{{#!highlight bash
# --- install python2
sudo apt install python2
# --- install pip2
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py
sudo python2 get-pip.py
# --- install virtualenv
pip2 install virtualenv
# --- create env
virtualenv -p /usr/bin/python2 venv
# --- activate
source venv/bin/activate
# --- install package
python setup.py install
# --- deactivate
deactivate

}}}

== Metrics ==

Получаем текущее значение метрики

{{{#!highlight python
prom.preparation_time._value.get()
prom.transfer_files_time._value.get()

}}}

== WSGI ==

WSGI - это то, что связывается web-сервер (nginx, apache) с приложением, написанным на python.

    . Видимо нечто типа  Passenger для Ruby

https://habr.com/ru/post/426957/

== SQLAlchemy ==

{{{#!highlight python
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
from sqlalchemy.sql import select

# Create a database engine
engine = create_engine('postgresql://user:password@localhost/mydatabase')

# Create a metadata object
metadata = MetaData()

# Define a table
users_table = Table('users', metadata,
                    Column('id', Integer, primary_key=True),
                    Column('name', String),
                    Column('email', String))

# Create the table in the database (if it doesn't already exist)
metadata.create_all(engine)

# Define some data to insert or update
data = {'name': 'John Doe', 'email': 'johndoe@example.com'}

# Create a SELECT statement to check if the user already exists
select_stmt = select([users_table]).where(users_table.c.email == data['email'])

# Execute the SELECT statement
result = engine.execute(select_stmt)

# Check if the user already exists
existing_user = result.fetchone()

if existing_user:
    # User already exists, so update their information
    update_stmt = users_table.update().where(users_table.c.email == data['email']).values(name=data['name'])
    engine.execute(update_stmt)
else:
    # User doesn't exist, so insert their information
    insert_stmt = users_table.insert().values(name=data['name'], email=data['email'])
    engine.execute(insert_stmt)

}}}

== Swarm ==

{{{#!highlight python
import docker
import os
DOCKER_BASE_URL = os.environ.get('DOCKER_BASE_URL', 'unix://tmp/docker.sock')
docker_client = docker.DockerClient(base_url=DOCKER_BASE_URL)
docker_client.services.list()
docker_client.services.list()[3].tasks()

}}}