Reputation: 812
I have a Python project which I created according to basic Poetry instructions.
The project folder is something like this:
my-project
+----my_project
| +-- my_project.py
| +-- File1.py
| +-- File2.py
|
+----pyproject.toml
Example of how I import stuff from one file to another: in my_project.py
I have the code
from . import File1, File2
If I want to debug this from VS Code, if I try F5
in the my_project.py
, I get the error:
Exception has occurred: ImportError
attempted relative import with no known parent package
However, if I don't express the imports like above, I can't run it using the poetry
command.
In the pyproject.toml
file, I have this:
[tool.poetry.scripts]
my-project = "my_project.my_project:run"
run
is the entry-point method in the my_project.py
file.
To run the project from command prompt, I go to the project folder (where the package folder is) and I type poetry run my-project
Again, up to this point, everything according to the Poetry documentation.
How could I debug this project in VS Code?
I know I need to create a launch.json
file, but I don't know how the configuration should look.
Upvotes: 26
Views: 37817
Reputation: 13518
For Visual Studio Code, you could try this:
__init__.py
file in the sub-directory my_project
.vscode
directory, add a launch.json
file with the following content:{
"version": "0.1.0",
"configurations": [
{
"name": "my-project",
"type": "debugpy",
"request": "launch",
"cwd": "${workspaceFolder}",
"module": "my_project",
"args": []
}
]
}
Here, cwd
points to your workspace folder, which should be the parent directory of my-project
.
You should then be able to run successfully the Run and Debug
module of Visual Studio Code.
As for Poetry, try modifying your pyproject.toml
like this (there seems to be a typo, hyphen vs underscore):
[tool.poetry.scripts]
my-project = "my-project.my_project:run"
And make sure to set the parent directory of my-project
as your current working directory when you run poetry run my-project
.
See this post for additional guidance.
Upvotes: 15
Reputation: 395
launch.json
configuration that worked for me where I have a poetry script defined as an alias command in the pyproject.toml
...
"name": "Poetry script...",
"type": "debugpy", // 'python' works too but is legacy
"request": "launch",
"program": "${workspaceFolder}/path/to/python/module.py",
"console": "integratedTerminal",
"cwd": "${workspaceFolder}",
"args": [
"your",
"args"
],
"env": {
"POETRY_ACTIVE": "1"
}
}
...
Upvotes: 0
Reputation: 1179
poetry env info
in your project rootVirtualenv.Executable
to python
${workspaceFolder:<project-root-folder-name>}
for cwd
This is a launch.json example, I run my fastapi app with gunicorn in a workspace using PYTHON_ENV=prod poetry run gunicorn -c gunicorn_conf.py project.main:app --bind 0.0.0.0:8081
{
"version": "0.1",
"configurations": [
{
"name": "Python: Poetry",
"type": "debugpy",
"request": "launch",
"python": "/home/admin/.cache/pypoetry/virtualenvs/project-ESoVRWd5-py3.10/bin/python",
"module": "gunicorn",
"args": [
"-c",
"gunicorn_conf.py",
"project.main:app",
"--bind",
"0.0.0.0:8081"
],
"env": { "PYTHON_ENV": "prod" },
"cwd": "${workspaceFolder:core}",
"console": "integratedTerminal"
}
]
}
Upvotes: 0
Reputation: 762
To expand on Laurent's great answer here is an updated configuration that will run poetry itself and automatically select the virtual environment:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python Debugger: Poetry my-project with Arguments",
"type": "debugpy",
"request": "launch",
"console": "integratedTerminal",
"stopOnEntry": false,
"justMyCode": true,
"python": "${command:python.interpreterPath}",
"cwd": "${workspaceFolder}",
"args": "${command:pickArgs}",
"module": "poetry run my-project",
}
]
}
Hopefully this helps anyone coming here from a search engine.
Upvotes: 1
Reputation: 340
My proposed solution using the extension Command Variable to set up a configuration in launch.json
.
Using the Command Variable extension, we can use a "variable transform" to convert the current file path into a relative path with dots.
This would give the following configuration in launch.json
:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python (Poetry): Current File",
"type": "python",
"request": "launch",
"module": "${command:extension.commandvariable.file.relativeFileDotsNoExtension}",
"console": "integratedTerminal",
"justMyCode": true
}
]
}
So, for a project that looks like:
WorspaceRoot
┬───────────
│
├─┬─ .vscode
│ └─── launch.json
├─┬─ MyProject
│ ├─── __init__.py
│ ├─── file1.py
│ ├─── file2.py
│ └─── ...
├─── poetry.lock
├─── pyproject.toml
└─── ...
by running the configuration on an open file in WorkspaceRoot/MyProject/file1.py
, the command command:extension.commandvariable.file.relativeFileDotsNoExtension
converts the file path into MyProject.file1
. If you have the current Python environment set to be your poetry project, running this should run as a module (essentially -m
).
If, however, you have a slightly different project structure, where file1.py
is located in WorspaceRoot/src/MyProject/file1.py
, then this needs additional work since the passed module will be src.MyProject.file1
.
To remove the src
prefix, we can make use an input variable along with the extension's command extension.commandvariable.transform
, as follows:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python (Poetry): Current File",
"type": "python",
"request": "launch",
"module": "${input:PythonModuleName}",
"console": "integratedTerminal",
"justMyCode": true
}
],
"inputs": [
{
"id": "PythonModuleName",
"type": "command",
"command": "extension.commandvariable.transform",
"args": {
"text": "${command:extension.commandvariable.file.relativeFileDotsNoExtension}",
"find": "src\\.(.*)",
"replace": "$1",
}
}
]
}
The regex pattern src\\.(.*)
captures everything after the src.
prefix, which is then substituted as the input to our original configuration via the ${input:PythonModuleName}
variable replacement.
Upvotes: 0
Reputation: 345
None of above worked for me. I have tried this
First run poetry debug info
and get your executable path
and then
{
"version": "0.1",
"configurations": [
{
"name": "Python: Poetry",
"type": "python",
"request": "launch",
"python": "your executeable path taken from command above",
"module": "yourmodulename",
"args": [],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
}
I hope it helps :)
Upvotes: 10
Reputation: 177
The previous answers didn't work for me.
Here is the configuration of the launch.json
file I needed to use to get the python debugger running on Visual Studio Code in a Poetry project.
{
"version": "0.2.0",
"configurations": [
{
"name": "project debug", // Anything you want
"type": "python",
"request": "launch",
"cwd": "C:\\...\\project", // full path to project folder
"python": "C:\\...\\python.exe", // full path to python.exe (run poetry env info --path) in terminal to get virtual env folder
"program": "C:\\...\\file.py", // full path to file to execute
"console": "integratedTerminal",
"redirectOutput": true,
"justMyCode": false,
"stopOnEntry": false,
}
]
}
And here's the structure I use(d) for Poetry projects
C:.
│ poetry.lock
│ pyproject.toml
│
├───.vscode
│ launch.json
│
├───decon
│ │ file1.py
│ │ file2.py
│ │ ...
│ │ __init__.py
Upvotes: 4
Reputation: 116
In the project directory, create the file .vscode/launch.json
with the following structure:
{
// 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": "Your Project Name",
"type": "python",
"request": "launch",
"cwd": "${workspaceFolder}",
"module": "poetry",
"python": "${workspaceFolder}/.venv/bin/python",
"args": [
"run",
"python",
"-m",
"uvicorn",
"your_app_project:app",
"--host",
"localhost",
"--port",
"8000",
"--debug",
"--reload"
],
"justMyCode": true,
"stopOnEntry": false,
"console": "integratedTerminal",
"env": {
"SIMPLE_SETTINGS": "your_env_value"
}
}
]
}
Adjust the name
, the args
, and the env
to fit your project. If you are using pip
, the value of the module field should be pytest
.
It is also possible to add more configurations and change them during development.
Upvotes: 6