Skip to content
This repository was archived by the owner on May 20, 2025. It is now read-only.

Commit ddfbd90

Browse files
raksivjyecuschHomelessDinosaurdavemooreuws
authored
Add guide for connecting a debugger for python projects. (#726)
Co-authored-by: Jye Cusch <[email protected]> Co-authored-by: Ryan Cartwright <[email protected]> Co-authored-by: David Moore <[email protected]>
1 parent 6335a41 commit ddfbd90

File tree

6 files changed

+187
-0
lines changed

6 files changed

+187
-0
lines changed

dictionary.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,9 @@ preflight
240240
lifecycle
241241
NodeJS
242242
priviledge
243+
breakpoint
244+
debugpy
245+
vscode
243246
APIS
244247
TLS
245248
SRE
@@ -256,6 +259,7 @@ VMs
256259
CDN
257260
subdirectories
258261
AzureTF
262+
VSCode
259263
[0-9]+px
260264
^.+[-:_]\w+$
261265
[a-z]+([A-Z0-9]|[A-Z0-9]\w+)

docs/guides/python/debugging.mdx

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
---
2+
description: 'How to debug Nitric Python applications locally'
3+
tags:
4+
- Debugging
5+
languages:
6+
- python
7+
published_at: 2025-04-01
8+
updated_at: 2025-04-01
9+
---
10+
11+
# Local Debugging with Python
12+
13+
Debugging serverless-style applications can be challenging due to the way functions are triggered by events.
14+
15+
This guide will walk you through setting up local debugging for Nitric applications written in Python, using VSCode. We will use [`debugpy`](https://github.com/microsoft/debugpy) to connect a debugger to the service while it runs.
16+
17+
## 1. Add debugpy to our project
18+
19+
```bash
20+
uv add debugpy
21+
```
22+
23+
## 2. Modify the Python entry point
24+
25+
Add the following lines to the top of the service file (e.g., `services/api.py`). This starts a debug server that the IDE can attach to.
26+
27+
<Note>
28+
This code is for local development only and must not be included in production
29+
deployments.
30+
</Note>
31+
32+
```python
33+
import debugpy
34+
35+
host, port = debugpy.listen(("0.0.0.0", 52509)) # Static port for consistent debugging
36+
print(f"✅ Debugpy is listening on {host}:{port}", flush=True)
37+
```
38+
39+
<Note>
40+
A **static port** (`52509`) is used so the IDE knows which port to connect to.
41+
Update the `launch.json` configuration to match this port before starting the
42+
debugger.
43+
</Note>
44+
45+
## 3. Update start command
46+
47+
Modify the `start` command to include an auto-reloader and ensure Python does not use frozen modules, which can interfere with `debugpy`:
48+
49+
```yaml title: nitric.yaml
50+
name: my-project
51+
services:
52+
- basedir: ''
53+
match: services/*.py
54+
runtime: python
55+
start: uv run -- watchmedo auto-restart -p "*.py" --no-restart-on-command-exit -R -- python -Xfrozen_modules=off $SERVICE_PATH
56+
batch-services: []
57+
websites: []
58+
runtimes:
59+
python:
60+
dockerfile: ./python.dockerfile
61+
context: ''
62+
args: {}
63+
```
64+
65+
<Note>
66+
This configuration restarts the service on file changes and includes the
67+
necessary flags for debugging compatibility.
68+
</Note>
69+
70+
## 4. Configure VS Code
71+
72+
VS Code uses a `.vscode/launch.json` file to define how it should start or attach to a debugging session. In this case, the debugger doesn't launch the application itself—it attaches to the running service that was started manually from the terminal.
73+
74+
To create or update the launch.json file:
75+
76+
- Open the Run and Debug panel in VS Code (Ctrl+Shift+D or from the sidebar).
77+
- Click "create a launch.json file" if one doesn't already exist.
78+
- Choose "Python" when prompted for the environment.
79+
- Replace the default configuration with the following:
80+
81+
```json title: ./vscode/launch
82+
{
83+
"version": "0.2.0",
84+
"configurations": [
85+
{
86+
"name": "Python Debugger: Remote Attach",
87+
"type": "debugpy",
88+
"request": "attach",
89+
"connect": {
90+
"host": "localhost",
91+
"port": 52509
92+
},
93+
"pathMappings": [
94+
{
95+
"localRoot": "${workspaceFolder}",
96+
"remoteRoot": "."
97+
}
98+
]
99+
}
100+
]
101+
}
102+
```
103+
104+
<Note>
105+
Ensure the `port` matches the value used in the `debugpy.listen()` call. If
106+
the port changes in the code, update it here as well.
107+
</Note>
108+
109+
## 5. Running the debugger
110+
111+
Start your nitric service with `nitric start`, in the Terminal, both the Nitric runtime output and the debugpy listener output will be visible, including the active debug port.
112+
113+
![vscode](/docs/images/guides/python-debugging/terminal.png)
114+
115+
Now run the debugger and add breakpoints or watch variables.
116+
117+
![vscode](/docs/images/guides/python-debugging/debug.png)
118+
119+
## 6. Handling multiple services
120+
121+
Nitric applications typically have more than one service, however, `debugpy` only supports listening on a single (host, port) pair per service.
122+
123+
Your services will each have the following snippet with a unique port which will configure in our `launch.json`.
124+
125+
```python
126+
import debugpy
127+
128+
host, port = debugpy.listen(("0.0.0.0", 52509))
129+
print(f"✅ Debugpy is listening on {host}:{port}", flush=True)
130+
```
131+
132+
You can update your vscode configuration to use compounds, for example if you had two services:
133+
134+
```json title: ./vscode/launch
135+
{
136+
"version": "0.2.0",
137+
"compounds": [
138+
{
139+
"name": "Attach to Both Services",
140+
"configurations": [
141+
"Python Debugger: Service 1",
142+
"Python Debugger: Service 2"
143+
]
144+
}
145+
],
146+
"configurations": [
147+
{
148+
"name": "Python Debugger: Service 1",
149+
"type": "debugpy",
150+
"request": "attach",
151+
"connect": {
152+
"host": "localhost",
153+
"port": 52509
154+
},
155+
"pathMappings": [
156+
{
157+
"localRoot": "${workspaceFolder}",
158+
"remoteRoot": "."
159+
}
160+
]
161+
},
162+
{
163+
"name": "Python Debugger: Service 2",
164+
"type": "debugpy",
165+
"request": "attach",
166+
"connect": {
167+
"host": "localhost",
168+
"port": 52510
169+
},
170+
"pathMappings": [
171+
{
172+
"localRoot": "${workspaceFolder}",
173+
"remoteRoot": "."
174+
}
175+
]
176+
}
177+
]
178+
}
179+
```
180+
181+
Now in `Run and Debug` you can select `Attach to both`:
182+
183+
![vscode](/docs/images/guides/python-debugging/attachboth.png)
31 KB
Loading
216 KB
Loading
264 KB
Loading
76.2 KB
Loading

0 commit comments

Comments
 (0)