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

Commit cca8466

Browse files
committed
Update images and address feedback around multiple services
1 parent 747f255 commit cca8466

File tree

6 files changed

+105
-20
lines changed

6 files changed

+105
-20
lines changed

docs/guides/python/debugging.mdx

Lines changed: 105 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,46 @@ published_at: 2025-03-27
88
updated_at: 2025-03-27
99
---
1010

11-
# Debugging
11+
# Local Debugging with Python
1212

13-
This guide will walk you through setting up local debugging for Nitric applications written in Python, using VSCode.
13+
Debugging serverless-style applications can be challenging due to the way functions are triggered by events.
1414

15-
## Local Debugging with Python
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.
1616

17-
Debugging serverless-style applications can be challenging due to the way functions are triggered by events. For Python, we can use [`debugpy`](https://github.com/microsoft/debugpy) to connect a debugger to the service while it runs.
17+
## 1. Add debugpy to our project
1818

19-
### 1. Modify the Python entry point
19+
```bash
20+
uv add debugpy
21+
```
22+
23+
## 2. Modify the Python entry point
2024

2125
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.
2226

27+
<Note>
28+
This code is for local development only and must not be included in production
29+
deployments.
30+
</Note>
31+
2332
```python
2433
import debugpy
2534

2635
host, port = debugpy.listen(("0.0.0.0", 52509)) # Static port for consistent debugging
2736
print(f"✅ Debugpy is listening on {host}:{port}", flush=True)
2837
```
2938

30-
> A **static port** (`52509`) is used so the IDE knows which port to connect to. Update the `launch.json` configuration to match this port before starting the debugger.
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>
3144

32-
### 2. Update `nitric.yaml`
45+
## 3. Update start command
3346

34-
Modify the `start` command to include an auto-reloader and ensure Python does not use frozen modules, which can interfere with `debugpy`, E.g.
47+
Modify the `start` command to include an auto-reloader and ensure Python does not use frozen modules, which can interfere with `debugpy`:
3548

36-
```yaml
37-
name: message-board
49+
```yaml title: nitric.yaml
50+
name: my-project
3851
services:
3952
- basedir: ''
4053
match: services/*.py
@@ -49,11 +62,14 @@ runtimes:
4962
args: {}
5063
```
5164
52-
> This configuration restarts the service on file changes and includes the necessary flags for debugging compatibility.
65+
<Note>
66+
This configuration restarts the service on file changes and includes the
67+
necessary flags for debugging compatibility.
68+
</Note>
5369
54-
### 3. Configure `launch.json` in VS Code
70+
## 4. Configure VS Code
5571
56-
VS Code uses a `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.
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.
5773

5874
To create or update the launch.json file:
5975

@@ -62,7 +78,7 @@ To create or update the launch.json file:
6278
- Choose "Python" when prompted for the environment.
6379
- Replace the default configuration with the following:
6480

65-
```json
81+
```json title: ./vscode/launch
6682
{
6783
"version": "0.2.0",
6884
"configurations": [
@@ -85,14 +101,83 @@ To create or update the launch.json file:
85101
}
86102
```
87103

88-
> Ensure the `port` matches the value used in the `debugpy.listen()` call. If the port changes in the code, update it here as well.
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
89127

90-
### 4. Running the debugger
128+
host, port = debugpy.listen(("0.0.0.0", 52509))
129+
print(f"✅ Debugpy is listening on {host}:{port}", flush=True)
130+
```
91131

92-
Start your nitric service with `nitric start` and start the debugger.
132+
You can update your vscode configuration to use compounds, for example if you had two services:
93133

94-
![vscode](/docs/images/guides/python-debugging/debugger.png)
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+
```
95180

96-
In the Terminal, both the Nitric runtime output and the debugpy listener output will be visible, including the active debug port.
181+
Now in `Run and Debug` you can select `Attach to both`:
97182

98-
In this example, a breakpoint has been hit on line 16 of `message_api.py`, within an HTTP handler for the `/messages` endpoint.
183+
![vscode](/docs/images/guides/python-debugging/attachboth.png)
31 KB
Loading
216 KB
Loading
264 KB
Loading
-600 KB
Binary file not shown.
76.2 KB
Loading

0 commit comments

Comments
 (0)