- PVSM.RU - https://www.pvsm.ru -
Это небольшой туториал о настройке VS Code для работы с python. Здесь вы не увидите каких-то божественных откровений — тут будет просто мой опыт о том, как сделать свою работу/хобби немного комфортнее и почему я пришел именно к такой конфигурации.
Мой путь к разработке начался через администрирование, и, как и любой админ, я сталкивался с необходимостью писать автоматизацию. Bash/python/powershell/go — это все типичные инструменты инженера. Но в большинстве своем мы пишем автоматизацию в vim/nano/notepad++. И на все рассказы про IDE я лишь пожимал плечами — "а мне то это зачем?". Но однажды появился проект на Python, где я стал писать код уже "в промышленных масштабах"… Результат предсказуем — я пересел на VS Code.
Почему он? Да все просто:
Я осознал прелесть линтера (линтер (linter) — это программа, которая автоматизирует «причёсывание» кода по определённым правилам), подсказки синтаксиса, и прочие прелести современных IDE.
Но разбираться в VS Code "все еще было некогда". И в один прекрасный момент за эту лень я поплатился сполна — у меня закрылся VScode с ошибкой и при запуске у меня открылось пустое окно. Это был шок. Привычка писать в пустых файлах, кое-как настроенные параметры запуска отладки, настройки linter-а и подсказок по синтаксису — все это в полной мере дало о себе знать. И в итоге было принято решение разобраться что тут к чему и как мне сохранить свои настройки.
В итоге мое изучение VS Code разделилось на три этапа:
Из коробки VS Code можно назвать "весьма продвинутым блокнотом". В общем то так бы все и осталось, если бы не система плагинов — с их помощью можно превратить VS Code практически во что угодно.
Теперь немного теории, чтобы мы одинаково понимали используемые термины и у нас был единый контекст. Почему это в моем понимании важно? Да потому что я мучался с этим достаточно долго, пока не собрал свою порцию шишек и граблей.
Понятия:
Область видимости настроек:
Файлы и их назначение:
В целом все просто — надо поставить сам python, поставить нужные расширения и сделать настройки. Кажется, что все банально, но как обычно "дьявол кроется в деталях".
Для того, чтобы начать разрабатывать на питоне с помощью VS Code надо сделать 3 вещи:
Плагины, необходимых для работы с python-ом:
Об этом я бы хотел тоже упомянуть, так как это очень удобная история. Есть такой набор плагинов от компании Microsoft — Remote Development (id — ms-vscode-remote.vscode-remote-extensionpack). Туда входят:
Все было очень просто, пока репозиторий был один. Кое-как я настроил какие-то совсем базовые вещи и на этом успокоился. Проблемы этого подхода всплыли тогда, когда репозиториев стало три и в одном из них использовался не python а Go. Ну и конечно же по классике — я не использовал venv =)
Вот небольшой список тех проблем, которые я испытывал постоянно:
Как я уже говорил, Workspace в VS Code это по сути свое область видимости настроек. Осознав это, я с ужасом понял, что мою идеологию "одно окно — много проектов" можно похоронить. Но остатки надежды говорили, что я не один такой и возможно решение есть среди тысяч плагинов, которые есть для VS Code. Но все оказалось даже лучше, начиная с версии 1.18 этот функционал доступен из коробки. И тут у меня начал вырисовываться примерный план приведения в порядок моего рабочего места разработчика. Он был в целом прост:
Сказано — сделано. В итоге у меня появился такая структура каталогов:
Development
├───.vscode
│ └───my_dev_env.code-workspace
├───First project
│ ├───!env
│ │ ├───prod.evn
│ │ └───dev.env
│ ├───.vscode
│ │ ├───launch.json
│ │ └───settings.json
│ └───app
│ ├───file111.txt
│ ├───file112.txt
│ └───...
├───Second project
│ ├───!env
│ │ ├───prod.evn
│ │ └───dev.env
│ ├───.vscode
│ │ ├───launch.json
│ │ └───settings.json
│ └───app
│ ├───file111.txt
│ ├───file112.txt
│ └───...
└───Third project
├───!env
│ ├───prod.evn
│ └───dev.env
├───.vscode
│ ├───launch.json
│ └───settings.json
└───app
├───file111.txt
├───file112.txt
└───...
Начнем по порядку:
Development/.vscode/my_dev_env.code-workspace.
тут лежат пути к папкам и общие настройки для всех Workspace. В этом файле мы определяем общие настройки на все проекты. Переопределить их можно с помощью локального файла с настройками — settings.json, он будет описан ниже. Пример файла (описание всех свойств даны в самом файле):
{
// Список папок, которые должны попасть в вашу multi-root.
// Пути можно использовать абсолютные, поэтому можно собирать
// воедино папки из разных мест
"folders": [
{
"path": "/Development/First project"
},
{
"path": "/Development/Second project"
},
{
"path": "/Development/Third project"
}
],
// Общие настройки. Они являются дефолтными для всех включенных директорий,
// но могут переопределяться на уровне конкретной корневой папки проекта.
// Тут собраны те, что использую я
"settings": {
"git.autofetch": true,
// Включить или выключить периодический поиск изменений в удаленном
// репозитории. В случае, если включено в VS Code в разделе работы
// с git будет показывать сколько неполученных коммитов есть
// в удаленном репозитории.
"python.languageServer": "Pylance",
// Выбор language server. У Python их несколько, с последнего времени
// по дефолту используется Pylance. На мой взгляд лучше оставить его,
// так как его делает Microsoft и он активно развивается.
"python.defaultInterpreterPath": "/opt/homebrew/bin/python3.10",
// Дефолтный путь для Питона
"python.analysis.diagnosticMode": "openFilesOnly",
// Выбор области, где производится анализ файлов на ошибки.
// Я выбрал вариант "только открытые файлы" чтобы меньше логало
"python.analysis.autoImportCompletions": true,
// Включает автоматическое добавление импорта модуля, если его нет,
// но в коде найдены на него ссылки
"python.analysis.typeCheckingMode": "off",
// Очень полезная, но очень суровая опция - включает проверку
// соответствия типов для языкового движка Pylance. По сути попытка
// сделать из Python типизированный язык. Доступные значения:
// off: анализ проверки типа не проводится; производится диагностика
// неразрешенных импортов/переменных
// basic: Правила, не связанные с проверкой типов (все правила в off)
// + базовые правила проверки типов
// strict: все правила проверки типов с наивысшей серьезностью ошибки
// (включая все правила в категориях off и basic)
"python.analysis.inlayHints.variableTypes": true,
// Анализирует ваши переменные и предлагает для них подходящие типы.
// Так же позволяет двойным кликом добавить тип
"python.analysis.inlayHints.functionReturnTypes": true,
// Анализирует ваши функции и классы и предлагает подходящие типы
// выходных данных. Так же дает подсказки, какой выходной тип вы получите
"python.terminal.activateEnvironment": true,
// Если в проекте найдено виртуальное окружение, то в терминале оно
// будет автоматически активироваться при переходе в этот проект
"python.linting.enabled": true,
// Включает линтер для питона
"python.linting.flake8Enabled": true,
// Выбор каким линтером пользоваться. Я выбрал flake8.
"python.linting.flake8Args": [
"--max-line-length=250",
// "--ignore=E402,F841,F401,E302,E305",
],
// Настройки flake8. Я лично выставил себе только увеличение максимальной
// длинны строки - по дефолту 80, этого мало для меня
"[python]": {
// Настройка автоматического форматирования. Удобно тем, что при сохранении
// автоматически приводит форматирование к правильному по мнению форматора виду
"editor.defaultFormatter":"ms-python.python",
// Выбор форматера
"editor.formatOnSave": true,
// Включает форматирование при сохранении
"editor.codeActionsOnSave": {
"source.organizeImports": true
// Форматирует импорты. Могут быть проблемы, если импорты зависят друг от друга
},
"files.exclude": {
// Крайне полезная на мой взгляд функция - задается список файлов, которые
// исключаются из показа в дереве каталогов. Отлично подходит для скрытия всяких
// ненужных системных каталогов
"**/.git": true,
"**/__pycache__": true,
"**/.DS_Store": true,
"**/Thumbs.db": true
},
"files.watcherExclude": {
// еще одна крайне любопытная опция - за изменениями файлов из
// этого списка VS Code не следит
"**/.git/objects/**": true,
"**/.git/subtree-cache/**": true,
"**/node_modules/*/**": true,
"**/.hg/store/**": true,
"**/__pycache__/**": true,
"**/.venv-*/**": true
},
"files.enableTrash": false,
// Включение/выключение корзины. Если False то файлы удаляются сразу же
"cSpell.language": "en,ru",
// Крайне полезный плагин и настройки - проверка орфографии.
// Настоятельно рекомендую к установке
"cSpell.words": [
// Тут список слов, которые мы добавили в исключения
"Clickhouse",
"fastapi",
"jsonify",
"loguru"
]
}
}
Далее идет папка .vscode внутри папки проекта. Тут мы видим два файла — settings.json и launch.json.
Файл settings.json нужен для того, чтобы переопределить параметры из одноименной секции файла workspace (my_dev_env.code-workspace). Вот пример файла
{
"python.defaultInterpreterPath": "${workspaceFolder}/.venv-first-project/bin/python3.10",
// Переопределяем путь к Python. Тут есть два интересных момента:
// 1. используется переменная ${workspaceFolder} - она обозначает
// корневую папку проекта
// 2. Путь указывает сразу же в каталог с виртуальным окружением
"python.envFile": "${workspaceFolder}/!env/dev.env",
// Крайне полезная директива - она позволяет задать переменные окружения,
// которые будут использоваться при запуске Python. Очень помогает при отладке
// при pytest, которым нужны переменные из окружения для работы
}
Файл launch.json нужен для настройки запуска отладки приложения. Оооо… Насколько же моя жизнь стала проще, когда я открыл для себя этот файл...
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
// Важно - можно делать сколько угодно наборов настроек отладки
{
"name": "First project - Dev",
// Наименование набора настроек для запуска и отладки. Выводится в
// выпадающем списке при запуске отладки. Мне нравится сюда вписывать проект
// и окружение, в котором будет запущена отладка
"type": "python",
// указание какой язык используется - нужно для запуска нужного
// набора параметров отладки
"request": "launch",
// Указывает режим, в котором следует начать отладку.
// - launch - если вы запускаете код локально
// - attach - если вы используете удаленную отладку
// (но эта история более сложная, поэтому тут я ее не буду описывать)
"program": "${file}",
// Путь к исполняемому файлу. По умолчанию ${file} обозначает файл,
// который выбран сейчас в активном окне. Если прописать туда какой-то
// конкретный файл, то запускается будет всегда он, вне зависимости
// от того, какое окно у вас сейчас выбрано.
"console": "integratedTerminal",
// Указатель того, куда выводить stdout и stderr.
// По умолчанию - встроенный терминал.
// Менять в моем понимании надо только если ты четко понимаешь что делаешь )
"python": "${workspaceFolder}/.venv/bin/python3.10",
// путь к интерпретатору, с помощью которого запускаться проект
"cwd": "${workspaceFolder}",
// Указывает каталог, из которого запускается для отладчика,
// который является базовой папкой для любых относительных путей,
// используемых в коде. Если опущено, по умолчанию используется ${workspaceFolder}.
"jinja": true,
// Активирует специфические параметры окружения для отладки шаблонов jinja
"envFile": "${workspaceFolder}/!env/dev.env",
// указывает на файл со списком переменных окружения.
// Есть нюанс - на данный момент не поддерживает многострочные переменные,
// то есть если вам нужно в окружение добавить большой json - придется
// сначала перевести его в компактный вид (в одну строку)
"justMyCode": true,
// Ограничивает отладку вашим кодом. В случае, если стоит False то отладчик будет
// показывать шаги и в стандартных библиотеках.
"presentation": {
// Настройки видимости этой настройки отладки в списке всех отладок
"hidden": false,
// Если True то эта отладка не будет видна в списках
"group": "api",
// Имя группы, нужно для логической группировки отладок
"order": 1
// Порядковый номер в группе
},
"autoReload": {
// Перезапуск отладки в случае сохранения файла с новым кодом.
// Если отладка идет в рамках активного файла - перезапустится только он.
"enable": true
}
},
// Пример настройки для запуска проекта написанного на FastApi
{
"name": "FastAPI",
"type": "python",
"request": "launch",
"module": "uvicorn",
// В отличие от предыдущего раза, где запускается файл из текущего активного окна,
// тут запускается вполне конкретный модуль
"console": "integratedTerminal",
"envFile": "${workspaceFolder}/!env/stage.env",
// Заведя несколько файлов с переменными окружения можно легко переключаться
// на отладку в разных окружениях
"python": "${workspaceFolder}/.venv/bin/python3.10",
"cwd": "${workspaceFolder}",
"args": [
// параметры запуска - специфичны для FastApi
"app.main:app",
// в моем случае:
// первое app- это пака в корне файла проекта
// main - это название файла,
// второе app - это имя экземпляра класса FastAPI
// (выглядит как app = FastAPI())
"--host",
"0.0.0.0"
// , "--workers", "5" // количество воркеров запускаемых по умолчанию.
// Нужно для высоконагруженного продакшена
],
"jinja": true,
"justMyCode": true,
"presentation": {
"hidden": false,
"group": "api",
"order": 5
}
}
]
}
В итоге, через 3 часа мучений все мои проекты были снабжены нужными им параметрами для запуска отладки, сделаны для всех свои виртуальные окружения и вообще наступила благодать. Но ненадолго...
И вот, казалось бы, наступило счастье, благодать, бабочки порхают и в мире больше не осталось проблем… Но радость была не долгой — мне пришлось работать с MSSQL, а с драйвер упорно не хотел становиться ко мне на машину. И тут я понял, что это следующий пинок — разобраться с возможностью разработки в контейнерах.
История с разработкой в контейнерах прямо внутри VS Code витала в моей голове уже очень давно, но как обычно, волшебного пинка не было. И вот он настал...
На самом деле у VS Code есть два режима поддержки контейнеров:
Теперь пара слов о том, как идеологически устроено использование контейнера в качестве полноценной среды разработки.
Шаги, которые происходят при запуске разработки в контейнере:
Вот так будет выглядеть наша структура каталогов для разработки в контейнерах:
Development
├───.vscode
│ └───my_dev_env.code-workspace
├───First project
│ ├───!env
│ │ ├───prod.evn
│ │ └───dev.env
│ ├───.devcontainer
│ │ ├───devcontainer.json
│ │ └───Dockerfile
│ ├───.vscode
│ │ ├───launch.json
│ │ └───settings.json
│ └───app
│ ├───file111.txt
│ ├───file112.txt
│ └───...
├───Second project
│ ├───!env
│ │ ├───prod.evn
│ │ └───dev.env
│ ├───.devcontainer
│ │ ├───devcontainer.json
│ │ └───Dockerfile
│ ├───.vscode
│ │ ├───launch.json
│ │ └───settings.json
│ └───app
│ ├───file111.txt
│ ├───file112.txt
│ └───...
└───Third project
├───!env
│ ├───prod.evn
│ └───dev.env
├───.devcontainer
│ ├───devcontainer.json
│ └───Dockerfile
├───.vscode
│ ├───launch.json
│ └───settings.json
└───app
├───file111.txt
├───file112.txt
└───...
Рассмотрим более подробно новые файлы.
devcontainer.json:
{
"name": "docker-my_project",
// Это имя будет показываться в интерфейсе VS Code и обозначать в каком
// контейнере вы работаете
"build": {
// Эта секция отвечает за то, как будет собираться ваш контейнер.
// Вариантов два - или собирать из Dockerfile при старте, или брать из
// какого-нибудь registry. Я пошел по первому варианту - он для меня проще
"dockerfile": "Dockerfile",
// Это самый обычный Dockerfile для сборки образа
"context": ".."
// Это очень важный параметр - он указывает в контексте какой директории
// собирается контейнер и относительно этой директории будут отрабатывать
// все пути в Dockerfile. В примере - это папка проекта First project.
// Соответственно, если у вас в Dockerfile написано "COPY app/requirements.txt ."
// то это значит, что при сборке каталог app будет искаться относительно папки
// First project. Эта возможность позволяет вам очень гибко собирать ваши образы.
},
"remoteUser": "root",
// Пользователь из-под кого запускается все в контейнере. Мне было лень
// заморачиваться и я оставил root.
// Есть еще две крайне любопытные команды - они позволяют вписать набор команд,
// выполняемых перед всеми действиями в контейнере (например, установка расширений)
// и сразу же после инициализации контейнера, перед передачей управления пользователю.
// Тут приведен пример, как можно это использовать - ставить зависимости
// или запускать сборки npm.
// "initializeCommand": "cp ../app/requirements.txt .",
// "postCreateCommand": "pip3 install -r /workspaces/alkir-infra-api/app/requirements.txt",
"extensions": [
// тут мы задаем список расширений VS Code, которые хотим увидеть при разработке в контейнере.
// Тут приведен мой - замените на свой.
"ms-python.python",
"wholroyd.jinja",
"formulahendry.code-runner",
"streetsidesoftware.code-spell-checker",
"VisualStudioExptTeam.vscodeintellicode",
"VisualStudioExptTeam.intellicode-api-usage-examples",
"humao.rest-client",
"streetsidesoftware.code-spell-checker-russian",
"adpyke.vscode-sql-formatter",
"mtxr.sqltools",
"ultram4rine.sqltools-clickhouse-driver",
"DotJoshJohnson.xml",
"redhat.vscode-yaml",
"njpwerner.autodocstring"
],
"customizations": {
// В этой секции вы переопределяете настройки по умолчанию.
// Логичнее всего скопировать сюда информацию из общего файла настроек.
"vscode": {
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python3.10",
"python.linting.enabled": true,
"sql-formatter.uppercase": true,
"python.linting.flake8Enabled": true
}
}
},
"forwardPorts": [
// Список портов, которые будут проброшены из контейнера.
// Нужно для того, чтобы обращаться к своему приложению внутри контейнера по сети.
// Так как у меня проект FastAPI он по умолчанию открывает 8000 порт на прослушивание.
8000
]
}
Пример Dockerfile для работы с Python
FROM python:3.10.8-buster as builder
COPY app/requirements.txt .
RUN set -ex
&& apt-get update -yqq
&& ACCEPT_EULA=Y apt-get install --no-install-recommends -yqq
unixodbc-dev
libpq-dev
g++
git
rsync
freetds-dev
freetds-bin
tdsodbc
&& pip3 install flake8 pylint autopep8
&& pip3 install -r requirements.txt
После того, как мы все настроили остается только запустить это все. Для этого надо нажать F1, и в появившейся строке ввода ввести "Open folder in container". После этого выбрать корневую папку проекта. После чего запустится сборка контейнера и папка откроется внутри контейнера.
И еще один момент. Как правильно, если вы хотите перезапустить контейнер или перестроить его у вас выпадает ошибка. Это, как правило, связано с тем, что контейнер не успевает удалиться. Попробуйте нажать retry и как правильно все срабатывает.
Так же, из неописанных возможностей (пока просто не разобрался), есть возможность стартовать зависимые контейнеры при запуске отладки. К примеру, вы разрабатывается фронт, и у вас в контейнерах стартуют бек с апи и субд для бека. Очень удобная штука.
Тут находится официальная документация — https://code.visualstudio.com/docs/ [2]
Открытая спецификация о разработке в контейнерах — https://containers.dev/ [3]
Поддерживаемые переменные в файлах настройки — https://code.visualstudio.com/docs/editor/variables-reference [4]
Настройки python — https://code.visualstudio.com/docs/python/settings-reference [5]
Перечень переменных в файле отладки — https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes [6]
Автор: Антон Литвинов
Источник [7]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/383110
Ссылки в тексте:
[1] неплохая статья: https://habr.com/ru/post/555502/
[2] https://code.visualstudio.com/docs/: https://code.visualstudio.com/docs/
[3] https://containers.dev/: https://containers.dev/
[4] https://code.visualstudio.com/docs/editor/variables-reference: https://code.visualstudio.com/docs/editor/variables-reference
[5] https://code.visualstudio.com/docs/python/settings-reference: https://code.visualstudio.com/docs/python/settings-reference
[6] https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes: https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes
[7] Источник: https://habr.com/ru/post/717110/?utm_source=habrahabr&utm_medium=rss&utm_campaign=717110
Нажмите здесь для печати.