Это небольшой туториал о настройке 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). Туда входят:
Лирическое отступление. 'Емае... Что ж я сделал то...' (с) реклама из 90-тых.
Все было очень просто, пока репозиторий был один. Кое-как я настроил какие-то совсем базовые вещи и на этом успокоился. Проблемы этого подхода всплыли тогда, когда репозиториев стало три и в одном из них использовался не 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
└───...
Начнем по порядку:
В итоге, через 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/
Открытая спецификация о разработке в контейнерах — https://containers.dev/
Поддерживаемые переменные в файлах настройки — https://code.visualstudio.com/docs/editor/variables-reference
Настройки python — https://code.visualstudio.com/docs/python/settings-reference
Перечень переменных в файле отладки — https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes
Часть первая. "Мы строили строили и наконец построили!" (с) один очень мудрый ушастый персонаж
Мой путь к разработке начался через администрирование, и, как и любой админ, я сталкивался с необходимостью писать автоматизацию. Bash/python/powershell/go — это все типичные инструменты инженера. Но в большинстве своем мы пишем автоматизацию в vim/nano/notepad++. И на все рассказы про IDE я лишь пожимал плечами — "а мне то это зачем?". Но однажды появился проект на Python, где я стал писать код уже "в промышленных масштабах"… Результат предсказуем — я пересел на VS Code.
Почему он? Да все просто:
- Быстрый
- Удобный
- Бесплатный
- Куча плагинов
Я осознал прелесть линтера (линтер (linter) — это программа, которая автоматизирует «причёсывание» кода по определённым правилам), подсказки синтаксиса, и прочие прелести современных IDE.
Но разбираться в VS Code "все еще было некогда". И в один прекрасный момент за эту лень я поплатился сполна — у меня закрылся VScode с ошибкой и при запуске у меня открылось пустое окно. Это был шок. Привычка писать в пустых файлах, кое-как настроенные параметры запуска отладки, настройки linter-а и подсказок по синтаксису — все это в полной мере дало о себе знать. И в итоге было принято решение разобраться что тут к чему и как мне сохранить свои настройки.
В итоге мое изучение VS Code разделилось на три этапа:
- Единые настройки на все проекты.
С этого я начал, но очень быстро понял, что мне необходимо делать отдельные настройки для разных проектов. - Отдельные настройки под каждый проект.
Почти идеальный вариант, если бы не проблемы со сборкой некоторых специфических библиотек под MacOS. - Разработка в контейнерах.
Очень интересный вариант разработки, лично мне он показался очень удобным.
Немного о идеологии VS Code.
Из коробки VS Code можно назвать "весьма продвинутым блокнотом". В общем то так бы все и осталось, если бы не система плагинов — с их помощью можно превратить VS Code практически во что угодно.
Теперь немного теории, чтобы мы одинаково понимали используемые термины и у нас был единый контекст. Почему это в моем понимании важно? Да потому что я мучался с этим достаточно долго, пока не собрал свою порцию шишек и граблей.
Понятия:
- Workspace
В VS Code работа очень многое крутиться вокруг такого понятия как Workspace. В заложенной логике Workspace — это папка с вашим проектом, область применение настроек и параметров запуска отладки.
Системные папки в Workspace и их назначение: - .vscode
Точка в начале — обязательна. В этой папке vscode ищет настройки окружения и запуска отладки для данного Workspace. - .devcontainer
Точка в начале — обязательна. В этой папке vscode ищет настройки контейнеров и Dockerfile для сборки для данного Workspace.
Область видимости настроек:
- User
Настройки сохраняются для конкретного пользователя - Workspace
Настройки сохраняются для конкретной области
Файлы и их назначение:
- %name%.code-workspace
Настройки для данного Workspace. Может содержать настройки плагинов, путей к интерпретатору и тому подобное. Удобно, можно передавать его другим. - launch.json
Настройка логики и параметров запуска отладки проекта. Может содержать несколько вариантов настройки для одного и того же проекта. - settings.json
Может содержать настройки плагинов, путей к интерпретатору и тому подобное. Переопределяет настройки из %name%.code-workspace. - devcontainer.json
Файл содержащие настройки процесса сборки контейнера и его содержимого
Что нужно для старта?
В целом все просто — надо поставить сам python, поставить нужные расширения и сделать настройки. Кажется, что все банально, но как обычно "дьявол кроется в деталях".
Настройка Python
Для того, чтобы начать разрабатывать на питоне с помощью VS Code надо сделать 3 вещи:
- Установить сами python (думаю с этим вы сами справитесь).
- Поставить набор плагинов для разработки (делается в самом VS Code, занимает минимум времени).
- Настроить различные дополнительные модули для более комфортной и качественной работы. Это:
- linter (я использую flake8).
- language server (настраивается в файле settings.json, я использую Pylance) (Вот тут неплохая статья описывающая что это и зачем это). Тут как раз обычно и скрыта вся магия.
- параметры запуска отладки (файл launch.json). Вторая часть магии.
Плагины, необходимых для работы с python-ом:
- Python Extension Pack (id — donjayamanne.python-extension-pack)
В этот плагин входит все, что нужно для разработки на python - Dev Containers (id — ms-vscode-remote.remote-containers)
Этот плагин нужен для работы в контейнерах
Настройка удаленной разработки
Об этом я бы хотел тоже упомянуть, так как это очень удобная история. Есть такой набор плагинов от компании Microsoft — Remote Development (id — ms-vscode-remote.vscode-remote-extensionpack). Туда входят:
- Remote — Tunnels
Назначение этого плагина не знаю, не разбирался - Dev Containers
Этот плагин позволяем нам разрабатывать и/или отлаживать код в контейнерах. Обязателен для установки, если хотите работать в контейнерах. - Remote — SSH
Этот плагин предназначен для удаленной разработки с подключением к удаленному хосту по ssh. Причем вы можете не только редактировать файлы или запускать команды, но и заниматься полноценной разработкой с отладкой и всем прочим. Проблема с сохранением файлов, на которых нет прав, может решить плагин sudo (Save as Root in Remote — SSH, id yy0931.save-as-root). - WSL
Этот плагин очень поможет пользователям Windows — с его помощью можно разрабатывать в среде полноценного Linux, подключаясь к нему через WSL.
Лирическое отступление. 'Емае... Что ж я сделал то...' (с) реклама из 90-тых.
Все было очень просто, пока репозиторий был один. Кое-как я настроил какие-то совсем базовые вещи и на этом успокоился. Проблемы этого подхода всплыли тогда, когда репозиториев стало три и в одном из них использовался не python а Go. Ну и конечно же по классике — я не использовал venv =)
Вот небольшой список тех проблем, которые я испытывал постоянно:
- Периодически отваливались импорты в python. Лечилось это переустановкой пакета и перезапуском приложения. (Да-да, это все еще было терпимо, так как происходило не часто)
- Запуск проектов был не самым простым делом, но я как настоящий самурай написал bash-скрипты для запуска. (Чего только не сделаешь, лишь бы не читать доки)
- Когда появился Go — на нем просто не работала отладка… В итоге отладкой я занимался в виртуалке…
Ну и добил меня случай, который я описал выше — я профукал настройки Workspace по дефолту.
И вот, мой дорогой читатель, сижу я перед ноутом, смотрю в пустую страницу VS Code и понимаю, что час настал...
Часть вторая. Single and multi-root workspace.
Как я уже говорил, 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 есть два режима поддержки контейнеров:
- полноценная разработка в контейнерах (будет рассматриваться в статье)
- отладка в контейнерах (мне показалась эта история более громоздкой, поэтому не ковырял)
Теперь пара слов о том, как идеологически устроено использование контейнера в качестве полноценной среды разработки.
- В гостевой операционной системе открывается интерфейс.
- Запускается контейнер, в который устанавливаются расширения и специальный сервер, который позволяет интерфейсной части взаимодействовать с контейнером по сети.
- В контейнер монтируется выбранная папка, то есть любые изменения файлов внутри контейнера происходят с файлами, лежащими на файловой системе вашей операционной системы.
- Все процессы, связанные работой с кодом, форматированием и отладкой запускаются внутри контейнера.
Шаги, которые происходят при запуске разработки в контейнере:
- Мы выбираем папку, которую хотим открыть в контейнере.
- VS Code ищет в корне этой папки специальную директорию .devcontainer.
- В этой директории ищется специальный файл — devcontainer.json. Он содержит в себе информацию о том, как запустить нужный контейнер.
- В случае, если мы собираем контейнер сами, то запускается процесс сборки с помощью Dockerfile из этой же директории.
- В случае, если мы пользуемся уже собранным контейнером из заданного регестри, то скачивается указанный нами образ.
- После того, как контейнер запустился, стартует команда, описанная в разделе "initializeCommand" из файла devcontainer.json (если они заданы).
- Следующим шагом запускается установка расширений внутрь контейнера. Список расширений указывается в файле devcontainer.json.
- После установки расширений стартует команда, описанная в разделе "postCreateCommand" из файла devcontainer.json (если они заданы).
Вот так будет выглядеть наша структура каталогов для разработки в контейнерах:
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/
Открытая спецификация о разработке в контейнерах — https://containers.dev/
Поддерживаемые переменные в файлах настройки — https://code.visualstudio.com/docs/editor/variables-reference
Настройки python — https://code.visualstudio.com/docs/python/settings-reference
Перечень переменных в файле отладки — https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes
VS Code, python, контейнеры — как обуздать эту триаду и разрабатывать внутри контейнера
Как пользоваться VS Code в полную силу Это небольшой туториал о настройке VS Code для работы с python. Здесь вы не увидите каких-то божественных откровений — тут будет просто мой опыт о том, как...
habr.com