Debug FastAPI application in VSCode - visual-studio-code

i'm trying to debug an application (a web api) that use FastAPI (uvicorn)
I'm also using poetry and set the projev virtual environment in vscode.
i read this tutorial to setup uvicorn and this one to setup vscode but i think i'm doing something wrong in set it up.
I tried to setup the launch.json both as python: module and python: current file
The problem seems that it doesn't recognize the project structure cause when i run the debug it stopped in an import statement with this error:
Exception has occurred: ImportError
attempted relative import with no known parent package
This is my current launch.json configuration:
"configurations": [
{
"name": "Python: local debug",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/src/topic_service/service/__init__.py",
"args" : ["--port", "8000"]
},
]
I also tried to add a .env file setting PYTHONPATH:
PYTHONPATH=.:${PYTHONPATH}
Locally i run the application as follow:
poetry run uvicorn src.main:app --port 8080 --reload
Does anyone know how to correctly setup vscode to debug an uvicorn application?
Thank you
UPDATE:
I also tried what this article says. the debugger seems to start but nothing happen (no breakpoint is triggered)

Try this configuration.
{
"name": "Python: Module",
"type": "python",
"request": "launch",
"module": "uvicorn",
"args": ["src.main:app","--reload"]
}

Likewise you provide uvicorn module with necessary args during development of FastAPI application, you need to configure your launch.json located in .vscode directory with respective values.
I did a write up for custom project configurations to debug FastAPI in VS Code here
Suppose you issue the following command to run FastAPI on uvicorn server with args mentioned as below
uvicorn main:app --reload --port 8000
then your launch.json should have module with value of uvicorn and each of the args separated by space as items of the args array.
"module": "uvicorn",
"type": "python",
"request": "launch",
"args": [
"main:app",
"--reload",
"--port",
"8000"
],
"env": {
"usersecret": "some$Ecret",
}
You can have this launch.json file in .vscode and then modify the args array in the JSON configuration as per your project 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": "Python: FastAPI",
"type": "python",
"request": "launch",
"module": "uvicorn",
"env": {
"db_username": "postgres",
"db_password": "secret",
"host_server": "localhost",
"database_name": "fastapi",
"ssl_mode": "prefer",
"db_server_port": "5432"
},
"args": [
"main:app",
"--reload",
"--port",
"8000"
]
}
]
}

For me worked with this configurations:
On Debug section on VSCode, choose create launch.json option. Probally it will open launch.json on .vscode folder in your root folder explorer
like this, inside of launch.json put this:
"version": "0.2.0",
"configurations": [
{
"name": "Python: FastAPI",
"type": "python",
"request": "launch",
"module": "uvicorn",
"cwd": "${workspaceFolder}/<folder to your main.py>",
"args": [
"main:app",
"--reload",
"--port", //these arg are optional
"3003"
]
}
]
}
Now , just run your debugger and have a nice day!
Edit: The cwd ensure that your debbuger will find the right path to your main.py file. So, for whos use multiple debuggers or uses outside vsCode with launch.json it's a nice choice use it.

The quick and easy way: launch debugger F5 and then select FastAPI Debug Configuration:
(p.s. this works on the VSCode Insiders; haven't tried it on a regular version)

The way i debug is quite basic, hope it helps
i have .py file with this config:
import uvicorn
from app.main import api
if __name__ == "__main__":
dev = 1
if dev==0:
#use this one
uvicorn.run(api, host="127.0.0.1", port=5000, log_level="info")
if dev == 1:
#or this one
uvicorn.run('app.main:api', host="127.0.0.1", port=5000, log_level="info", reload=True, debug=True)
if dev == 2:
uvicorn.run('app.main:api', host="127.0.0.1", port=5000, log_level="info", workers=2)
and run the file with the vscode debugger, the important thing is to run the app with the debug flag because otherwise the debugger skips the breakpoints (at least in my case)

Related

How can I change the capitalization of the project directory VS Code passes when debugging?

I'm running a Next.JS project in VS Code. My launch.json has the following configuration:
{
// ...
"configurations": [
{
"name": "Frontend: Dev Server",
"request": "launch",
"runtimeArgs": [
"run-script",
"dev",
"--preserve-symlinks", // To debug linked
],
"runtimeExecutable": "npm",
"skipFiles": [
"<node_internals>/**"
],
"type": "node",
}
],
}
When I run this configuration from VS Code, I get an error like the following:
C:\Program Files\nodejs\npm.cmd run-script dev --preserve-symlinks
> web-client#0.1.0 dev
> next dev -p 5555
warn - Invalid casing detected for project dir, received c:\etcetc actual path C:\etcetc, see more info here https://nextjs.org/docs/messages/invalid-project-dir-casing
I know that I want VS Code to pass in the drive letter in upper case instead of lower case, but I don't see any option to set that and I tried opening the project using code C:\etcetc directly.
How can I change the capitalization of the directory that VS Code applies to the launch configuration?
Add a current working directory to your launch.json configuration:
{
// ...
"configurations": [
{
"cwd": "${workspaceFolder}",
"name": "Frontend: Dev Server",
// ...
}
]
}
This passed an upper case drive letter to Node for me. You may also want to check that VS Code is opening the folder with the right case, i.e. node C:\etcetc.
If you still have casing errors, try deleting the .next directory.

How to configure VS code for pytest with environment variable

I am trying to debug pytest. I would like to inject an environment variable. Here is how I have set launch.json
{
"type": "python",
"request": "test",
"name": "pytest",
"console": "integratedTerminal",
"env": {
"ENV_VAR":"RandomStuff"
}
},
But it seems when I start debugging. I do not see the env variable injected, as a result my test which expects that env variable fails.
Also I notice error
Could not load unit test config from launch.json
pytest-env
Install
Per https://stackoverflow.com/a/39162893/13697228:
conda install -c conda-forge pytest-env
Or:
pip install pytest-env
pytest.ini
Create pytest.ini file in project directory:
[pytest]
env =
ENV_VAR=RandomStuff
Python
In your code, load environment variables as you normally would:
import os
env_var = os.environ["ENV_VAR"]
pytest / VS Code
Either run:
pytest
(Notice how it says configfile: pytest.ini)
C:\Users\sterg\Documents\GitHub\sparks-baird\mp-time-split> pytest
==================================== test session starts ===================================== platform win32 -- Python 3.9.12, pytest-7.1.1, pluggy-1.0.0 rootdir:
C:\Users\sterg\Documents\GitHub\sparks-baird\mp-time-split,
configfile: pytest.ini plugins: anyio-3.6.1, cov-3.0.0, env-0.6.2
collecting ...
Or:
This only seems to work with breakpoints that have manually been set, I'm guessing some other change is needed to pause on errors.
Python for VS Code Extension
Apparently the Python for VS Code extension recognizes a .env file automatically. E.g.
.env file:
ENV_VAR=RandomStuff
Haven't verified, but I'd assume this has the same behavior as using pytest-env with a pytest.ini file.
When all else fails
When I don't feel like dealing with the strange hackery necessary to get VS Code, Anaconda environments, and pytest playing nicely together (and/or forget how I fixed it before), I call my tests manually and run it like a normal script (see below). This may not work with more advanced pytest trickery using fixtures for example. At the end of your Python script, you can add something like:
if __name__ == "__main__":
my_first_test()
my_second_test()
and run it in debug mode (F5) as normal.
Could not really figure out how to fix "unit" test debugging with Vscode. But with Pytest one can call tests like python -m pytest <test file>(https://docs.pytest.org/en/stable/usage.html#cmdline)
That means Vscode can be configured like a module
"configurations": [
{
"name": "Python: Module",
"type": "python",
"request": "launch",
"module": "pytest",
"args": ["--headful","--capture=no", "--html=report.html"],
}
This is good enough to do debugging of python tests. Also you can then insert environment variables
"env": {
"ENV_VAR":"RandomStuff"
}
This works in v 1.72.2
Create in the workspace folder:
.vscode/launch.json
Similar to the OP, but using "module"
{
"version": "0.2.0",
"configurations": [
{
"name": "Pytest",
"type": "python",
"request": "launch",
"module": "pytest",
"console": "integratedTerminal",
"env": {
"testy": "someval"
}
}
]
}
Try some breakpoints (either in test files or app code)
Start the debugger
Watch the os.environ['testy'] value (must import os where the breakpoint is of course)

Visual Studio Code Task is Prepending the working directory to the command

I'm trying to setup visual studio code for rust to do debugging. In my launch.json file I have
{
"version": "0.2.0",
"configurations": [
{
"name": "(Windows) Launch",
"type": "cppvsdbg",
"request": "launch",
"program": "${workspaceRoot}/target/debug/vscode-rust-debug-example.exe",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"environment": [],
"externalConsole": true,
"preLaunchTask": "localcargobuildtask"
}
]
}
and in my tasks.json I have
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "localcargobuildtask",
"command": "echo hi",
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
Where "echo hi" is in my tasks I eventually want to have something like "cargo build" or "cargo test" or whatever. But this is just a starting step.
But when I press F5 the output I get is
> Executing task: C:\programs\VSCodeWorkspaces\RustProjects\vscode-rust-debug-example-debug-config-included\echo hi <
The terminal process terminated with exit code: 2
Terminal will be reused by tasks, press any key to close it.
Rather than running "echo" from where ever the terminal finds it (working directory first, then check global path variable like you would expect) it is actually looking for a program named "echo" in my root folder of the workspace.
How do I tell visual studio code "No I don't want you to run workspace/echo, I want you to run echo in workspace" ? Or is there another more direct way to tell visual studio code "compile this before you debug it" ?
The answer to this question How to debug Rust unit tests on Windows?
suggests that changing
"command": "cargo build",
into
"command": "cargo",
"args": [
"build"
],
in the tasks.json file works and somehow it does. Maybe the editor is configured to search the %path% for single word commands, or maybe some plugin I installed overwrote the "cargo" command. Maybe the reason echo wasn't found is because it is a terminal command, not a program. Maybe the error message was a lie and it was only reporting that it couldn't find workspacefolder\command despite checking %path%? Or maybe none of that. I have no idea. It is some pretty idiosyncratic behavior.

How to start both Angular app and WebApi service from VSCode on F5 or Ctrl+F5

I have top-level folder Homepage with the following structure:
--Homepage
----Client <- Angular app, created with `ng new` command
----Server <- .NET Core WebApi, created with `dotnet new webapi` command
I open VSCode at Homepage level:
I have these extensions installed:
Question
If I want to use single VSCode environment to work on both projects, Client and Server, is it possible to bind F5 (or Ctrl+F5) to start both projects together?
Client app I start using ng serve (it will run on http port 4200)
Server app I start using dotnet run (it will run on https port 5001)
I have just one common .vscode folder on Homepage (root level):
By default, when first created, the content of launch.json was this:
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (web)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/Server/bin/Debug/netcoreapp2.1/Server.dll",
"args": [],
"cwd": "${workspaceFolder}/Server",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart",
"launchBrowser": {
"enabled": true,
"args": "${auto-detect-url}",
"windows": {
"command": "cmd.exe",
"args": "/C start ${auto-detect-url}"
},
"osx": {
"command": "open"
},
"linux": {
"command": "xdg-open"
}
},
"env": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"sourceFileMap": {
"/Views": "${workspaceFolder}/Views"
}
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command:pickProcess}"
}
,]
}
So, when I press F5 it builds and start the Server app, the page opens at https://localhost:5001, from there I can navigate to https://localhost:5001/api/values and see WebApi works.
But the Client app doesn't start at all.
So, I thought if I add Debugger for Chrome extension's settings to launch.json, it should work, so I clicked on Add Configuration and added corresponding section:
{
"type": "chrome",
"request": "launch",
"name": "Launch Chrome",
"url": "http://localhost:4200",
"webRoot": "${workspaceFolder}"
},
I changed port from 8080 to 4200, since ng serve hosts on port 4200
But it does not start the Client app.
Please advice. Thanks
I have similar (node.js for API) and spent quite some times couldn't resolved, for example use && or &. Result is either API up or Angular up, never the both.
Anyway I finally realized have both Api and UI in the same folder/project/solution is not practical. An API is not specific to an UI, it's a universal DLL/service, should be siting somewhere by itself. So I separated them into two diff folders and have 2 VSC instances to run them:
start the API in debug mode
in 2nd VSC, run ng serve and let it take time to build
when ng says "Compiled successfully" go to launch.json to start the debug entry associated with Chrome
they work perfectly.

Start automatically python webserver from visual studio code

I would like to start automatically Python http.server when I'm hitting the run button (or F5) from visual studio code.
I assume it's the matter of the launch.json configuration but I'm not familiar with it.
How can I do that?
Please install the pythonVSCode extension. And create python file in your project directory. And place the below content on it. Refer here
import http.server
import socketserver
PORT = 8000
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print("serving at port", PORT)
httpd.serve_forever()
And create launch configuration like this...
{
"name": "Documentation",
"type": "python",
"request": "launch",
"stopOnEntry": false,
"pythonPath": "${workspaceRoot}/env/bin/python",
"program": "${workspaceRoot}/your_pyton_run_file.py",
"debugOptions": [
"WaitOnAbnormalExit",
"WaitOnNormalExit",
"RedirectOutput"
]
},
Then you can start this with F5