nvim-dap-python icon indicating copy to clipboard operation
nvim-dap-python copied to clipboard

[python] FastAPI debugging like vscode does

Open kasfil opened this issue 4 years ago • 4 comments

I tried to debug my FastAPI project but any configuration I tried never give me good result. Does anyone successfully debug FastAPI with nvim-dap?

this is my nvim dap configuration:

dap.adapters.python = {
    type = 'executable';
    command = 'python';
    args = { '-m', 'debugpy.adapter' };
}

dap.configurations.python = {
    {
        name = 'FastAPI debugger',
        type = 'python',
        request = 'launch',
        module = 'uvicorn',
        args = {
            "index:app",
            "--reload",
            "--reload-dir=api",
            "--reload-dir=app",
            "--reload-dir=common",
            "--reload-dir=dependency",
            "--reload-dir=models",
            "--reload-dir=schemas",
            "--use-colors"
        },
        console = "integratedTerminal"
    },
    {
        name = 'Python attach',
        type = 'python',
        request = 'attach',
        connect = {
            host = '127.0.0.1',
            port = 5678,
        }
    }
}

and this what i got from dap.log


[ DEBUG ] 2021-06-21T23:24:43Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:728 ]	"request"	{
  arguments = {
    adapterID = "nvim-dap",
    clientId = "neovim",
    clientname = "neovim",
    columnsStartAt1 = true,
    linesStartAt1 = true,
    locale = "en_US.UTF-8",
    pathFormat = "path",
    supportsRunInTerminalRequest = true,
    supportsVariableType = true
  },
  command = "initialize",
  seq = 0,
  type = "request"
}
[ DEBUG ] 2021-06-21T23:24:43Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  body = {
    category = "telemetry",
    data = {
      packageVersion = "1.3.0"
    },
    output = "ptvsd"
  },
  event = "output",
  seq = 1,
  type = "event"
}
[ DEBUG ] 2021-06-21T23:24:43Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  body = {
    category = "telemetry",
    data = {
      packageVersion = "1.3.0"
    },
    output = "debugpy"
  },
  event = "output",
  seq = 2,
  type = "event"
}
[ DEBUG ] 2021-06-21T23:24:43Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  body = {
    exceptionBreakpointFilters = { {
        default = false,
        filter = "raised",
        label = "Raised Exceptions"
      }, {
        default = true,
        filter = "uncaught",
        label = "Uncaught Exceptions"
      } },
    supportsClipboardContext = true,
    supportsCompletionsRequest = true,
    supportsConditionalBreakpoints = true,
    supportsConfigurationDoneRequest = true,
    supportsDebuggerProperties = true,
    supportsDelayedStackTraceLoading = true,
    supportsEvaluateForHovers = true,
    supportsExceptionInfoRequest = true,
    supportsExceptionOptions = true,
    supportsGotoTargetsRequest = true,
    supportsHitConditionalBreakpoints = true,
    supportsLogPoints = true,
    supportsModulesRequest = true,
    supportsSetExpression = true,
    supportsSetVariable = true,
    supportsStepInTargetsRequest = true,
    supportsTerminateDebuggee = true,
    supportsValueFormattingOptions = true
  },
  command = "initialize",
  request_seq = 0,
  seq = 3,
  success = true,
  type = "response"
}
[ DEBUG ] 2021-06-21T23:24:43Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:728 ]	"request"	{
  arguments = {
    args = { "index:app", "--reload", "--reload-dir=api", "--reload-dir=app", "--reload-dir=common", "--reload-dir=dependency", "--reload-dir=models", "--reload-dir=schemas", "--use-colors" },
    console = "integratedTerminal",
    module = "uvicorn",
    name = "FastAPI debugger",
    request = "launch",
    type = "python"
  },
  command = "launch",
  seq = 1,
  type = "request"
}
[ DEBUG ] 2021-06-21T23:24:43Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  arguments = {
    args = { "/home/kasf/.virtualenvs/fastapi-sqlalchemy/bin/python", "/home/kasf/.virtualenvs/fastapi-sqlalchemy/lib/python3.9/site-packages/debugpy/launcher", "43675", "--", "-m", "uvicorn", "index:app", "--reload", "--reload-dir=api", "--reload-dir=app", "--reload-dir=common", "--reload-dir=dependency", "--reload-dir=models", "--reload-dir=schemas", "--use-colors" },
    env = {},
    kind = "integrated",
    title = "Python Debug Console"
  },
  command = "runInTerminal",
  seq = 4,
  type = "request"
}
[ DEBUG ] 2021-06-21T23:24:43Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:48 ]	"run_in_terminal"	{
  args = { "/home/kasf/.virtualenvs/fastapi-sqlalchemy/bin/python", "/home/kasf/.virtualenvs/fastapi-sqlalchemy/lib/python3.9/site-packages/debugpy/launcher", "43675", "--", "-m", "uvicorn", "index:app", "--reload", "--reload-dir=api", "--reload-dir=app", "--reload-dir=common", "--reload-dir=dependency", "--reload-dir=models", "--reload-dir=schemas", "--use-colors" },
  env = {},
  kind = "integrated",
  title = "Python Debug Console"
}
[ DEBUG ] 2021-06-21T23:24:43Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:748 ]	"response"	{
  body = {
    processId = 4143
  },
  command = "runInTerminal",
  request_seq = 4,
  seq = 2,
  success = true,
  type = "response"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  event = "initialized",
  seq = 5,
  type = "event"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:728 ]	"request"	{
  arguments = {
    breakpoints = { {
        line = 191
      } },
    lines = { 191 },
    source = {
      name = "authbearer.py",
      path = "/home/kasf/Pypr/fastapi-sqlalchemy/dependency/authbearer.py"
    }
  },
  command = "setBreakpoints",
  seq = 3,
  type = "request"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  body = {
    breakpoints = { {
        id = 0,
        line = 191,
        source = {
          name = "authbearer.py",
          path = "/home/kasf/Pypr/fastapi-sqlalchemy/dependency/authbearer.py"
        },
        verified = true
      } }
  },
  command = "setBreakpoints",
  request_seq = 3,
  seq = 6,
  success = true,
  type = "response"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:728 ]	"request"	{
  arguments = {
    filters = { "uncaught" }
  },
  command = "setExceptionBreakpoints",
  seq = 4,
  type = "request"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  command = "setExceptionBreakpoints",
  request_seq = 4,
  seq = 7,
  success = true,
  type = "response"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:728 ]	"request"	{
  command = "configurationDone",
  seq = 5,
  type = "request"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  command = "configurationDone",
  request_seq = 5,
  seq = 8,
  success = true,
  type = "response"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  command = "launch",
  request_seq = 1,
  seq = 9,
  success = true,
  type = "response"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  body = {
    isLocalProcess = true,
    name = "uvicorn",
    pointerSize = 64,
    startMethod = "launch",
    systemProcessId = 4151
  },
  event = "process",
  seq = 10,
  type = "event"
}
[ DEBUG ] 2021-06-21T23:24:44Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  body = {
    reason = "started",
    threadId = 1
  },
  event = "thread",
  seq = 11,
  type = "event"
}
[ DEBUG ] 2021-06-21T23:24:45Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  body = {
    connect = {
      host = "127.0.0.1",
      port = 46289
    },
    console = "integratedTerminal",
    module = "uvicorn",
    name = "Subprocess 4168",
    python = { "/home/kasf/.virtualenvs/fastapi-sqlalchemy/bin/python" },
    request = "attach",
    subProcessId = 4168,
    type = "python"
  },
  event = "debugpyAttach",
  seq = 12,
  type = "event"
}
[ WARN ] 2021-06-21T23:24:45Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:546 ]	"No event handler for "	{
  body = {
    connect = {
      host = "127.0.0.1",
      port = 46289
    },
    console = "integratedTerminal",
    module = "uvicorn",
    name = "Subprocess 4168",
    python = { "/home/kasf/.virtualenvs/fastapi-sqlalchemy/bin/python" },
    request = "attach",
    subProcessId = 4168,
    type = "python"
  },
  event = "debugpyAttach",
  seq = 12,
  type = "event"
}
[ DEBUG ] 2021-06-21T23:24:45Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  body = {
    connect = {
      host = "127.0.0.1",
      port = 46289
    },
    console = "integratedTerminal",
    module = "uvicorn",
    name = "Subprocess 4167",
    python = { "/home/kasf/.virtualenvs/fastapi-sqlalchemy/bin/python" },
    request = "attach",
    subProcessId = 4167,
    type = "python"
  },
  event = "debugpyAttach",
  seq = 13,
  type = "event"
}
[ WARN ] 2021-06-21T23:24:45Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:546 ]	"No event handler for "	{
  body = {
    connect = {
      host = "127.0.0.1",
      port = 46289
    },
    console = "integratedTerminal",
    module = "uvicorn",
    name = "Subprocess 4167",
    python = { "/home/kasf/.virtualenvs/fastapi-sqlalchemy/bin/python" },
    request = "attach",
    subProcessId = 4167,
    type = "python"
  },
  event = "debugpyAttach",
  seq = 13,
  type = "event"
}
[ DEBUG ] 2021-06-21T23:25:11Z+0700 ] ...nvim/site/pack/packer/start/nvim-dap/lua/dap/session.lua:496 ]	{
  event = "terminated",
  seq = 14,
  type = "event"
}

kasfil avatar Jun 21 '21 16:06 kasfil

Looks like debugpy is trying to use an extension to the debug adapter protocol.

The debugpyAttach event is not part of the core protocol. According to their wiki this event is generated when the debugger detects a subprocess.

This might be something for nvim-dap-python as I'm not going to merge debug adapter specific extensions to nvim-dap, and nvim-dap extensions have the possibility to handle custom events.

What's a bit problematic is that it is not documented how the client is supposed to handle these custom events.

mfussenegger avatar Jun 22 '21 15:06 mfussenegger

Thank you, i'll close this issue and reopen in nvim-dap-python.

kasfil avatar Jun 23 '21 15:06 kasfil

Started work on this in https://github.com/mfussenegger/nvim-dap-python/pull/21

mfussenegger avatar Jul 08 '21 09:07 mfussenegger

I got it to work by following your comment on Django https://github.com/mfussenegger/nvim-dap-python/issues/7#issuecomment-755166718

  1. Instead of running uvicorn directly, I am calling main.py which has
import uvicorn

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)
  1. install debugpy inside the project virtualenv

for me that is

poetry run pip install -U debugpy
  1. launch application using debugpy
python -m debugpy --listen 5678 --wait-for-client main.py
  1. inside Neovim start nvim-dap and use Attach remote configuration, when asked continue with default server host and port

alternatively, I also had success with this configuration:

table.insert(dap.configurations.python, {
    type = 'python',
    request = 'launch',
    name = 'FastAPI',
    program = vim.fn.getcwd() .. '/main.py',
    pythonPath = function()
        return 'python'
    end,
})

then the application runs in a terminal window inside Neovim

disrupted avatar Sep 26 '21 19:09 disrupted

This should now be working with a debugpy version installed from git and with latest nvim-dap master.

(If it doesn't, please comment with a minimal reproduction so I can re-open and look into it)

mfussenegger avatar Feb 17 '23 14:02 mfussenegger