A self-hosted web interface and REST API for printing labels on a Brother QL-series printer from a Raspberry Pi.
SWAKES Print is a web application that runs on a Raspberry Pi and gives you a browser-based interface to design and print labels directly to a Brother QL-series label printer over USB, WiFi, or Ethernet. It also exposes a REST API so other systems can trigger prints programmatically.
Inspired by
brother_ql_webby Philipp Klaus — the original web interface for Brother QL printers. SWAKES Print was built on top of thebrother_qllibrary that powers it, extending the concept with a fully custom UI, REST API, favourites, print history, vCard QR support, and a settings panel.
- Print to any supported Brother QL-series printer over USB, WiFi, or Ethernet
- Supports multiple label sizes:
62×29mm,29×90mm,62×100mm,12mm,29mm - Live label preview canvas before printing
- Zoom control on the preview
- Print history — view the last 20 prints, each with a thumbnail and one-click Reprint button
- Address Label — name and up to four address lines, each independently sized and bold
- Food Label — name, date made, use-by date, and notes
- QR Code — four QR types:
- 🌐 Website — encode any URL
- 📝 Text — encode plain text
- 📶 WiFi — WPA/WPA2, WEP or open networks, with hidden SSID toggle
- 📇 vCard — full contact card (name, organisation, phone, email, website)
- Free Text — up to five independent text fields, each with custom font size, bold toggle, and drag-to-reposition
- Per-field font size control and bold toggle
- Drag elements to reposition on the canvas
- Add and position images on the label — drag, resize, and move freely including outside label bounds
- Upload and use custom fonts (.ttf / .otf)
- QR label text displayed beside the QR code with custom sizing
- Save any label configuration as a named favourite
- Load and restore a saved favourite instantly
- Delete favourites you no longer need
- Stored in
favourites.json— survives service restarts
- Appearance — change app name, subtitle, accent colour, and logo via the UI (no code edits needed)
- Fonts — upload custom fonts from within the settings panel
- Consumables — save a URL to your label supplier for quick access
- Export — download a zip of your full configuration (config, favourites, settings)
- System — restart the label service from the browser
- Printer — select your printer model, backend, and device address from the UI
- Responsive layout with Form / Preview tab switching on small screens
- Touch-friendly input sizing
- Prevents iOS auto-zoom on input focus
Trigger prints from any device on the network:
GET /api/print?text=Hello&size=40
POST /api/print — multipart/form-data, image_file=<binary>
POST /api/print — JSON, {"image_base64": "..."}
GET /api/print?image_url=https://…/img.png
GET /api/print?template=Address+Label&name=John&address1=123+Main
GET /api/print?template=QR+Code&qr_type=wifi&wifi_ssid=Net&wifi_password=pass
SWAKES Print uses the brother_ql library and supports the following Brother QL-series printers. The printer model can be selected from Settings → Printer without editing any config files.
| Model | Verified | Notes |
|---|---|---|
| QL-500 | ✓ | No compression, no auto-cut |
| QL-550 | ✓ | |
| QL-560 | ✓ | |
| QL-570 | ✓ | Tested model |
| QL-580N | ||
| QL-650TD | ||
| QL-700 | ✓ | |
| QL-710W | ✓ | WiFi capable |
| QL-720NW | ✓ | WiFi/Ethernet |
| QL-800 | ✓ | Black + red two-colour printing |
| QL-810W | ✓ | WiFi, two-colour |
| QL-820NWB | ✓ | WiFi/Bluetooth, two-colour |
| QL-1050 | ✓ | Wide format (102mm) |
| QL-1060N | ✓ | Wide format, network |
| QL-1100 | ✓ | Wide format (102mm) |
| QL-1110NWB | Wide format, WiFi/Bluetooth | |
| QL-1115NWB | Wide format, WiFi/Bluetooth |
✓ = verified by
brother_qlcontributors. Unverified models may still work.
Connection backends supported:
pyusb— USB connection, works cross-platformnetwork— WiFi or Ethernet (tcp://192.168.x.x:9100)linux_kernel— USB via/dev/usb/lp0, Linux only
Note: If your printer has an Editor Lite mode, disable it before connecting via USB — hold the button until the LED turns off.
- Raspberry Pi (any model with USB; tested on Raspberry Pi 4)
- Any supported Brother QL-series printer (see table above)
- USB cable (or network connection for WiFi/Ethernet models)
- Raspberry Pi OS (Bullseye or later recommended)
- Python 3.9+
pipandvenv
git clone https://github.com/pqpxo/swakes-print.git
cd swakes-printpython3 -m venv venv
source venv/bin/activatepip install flask pillow qrcode[pil] brother-ql requests pyusbEdit config.json to match your printer and label, or use Settings → Printer in the UI after first run:
{
"printer": {
"model": "QL-570",
"device": "usb://0x04f9:0x2042",
"backend": "pyusb"
},
"label": {
"default_size": "62x29",
"supported_labels": ["62x29", "29x90", "62x100", "12", "29"],
"canvas_width": 696,
"canvas_height": 271,
"default_font": "DejaVuSans.ttf",
"default_font_size": 32
}
}To find your printer's USB vendor/product ID:
lsusb
# Look for Brother Industries — e.g. ID 04f9:2042For WiFi/Ethernet models, set the backend and device accordingly:
{
"printer": {
"model": "QL-710W",
"device": "tcp://192.168.1.50:9100",
"backend": "network"
}
}Allow the Pi user to access the USB printer without sudo:
sudo nano /etc/udev/rules.d/99-brother-ql.rulesAdd the following line (replace with your vendor/product ID):
SUBSYSTEM=="usb", ATTR{idVendor}=="04f9", ATTR{idProduct}=="2042", MODE="0666"
Then reload:
sudo udevadm control --reload-rules
sudo udevadm triggerpython3 app.pyOpen your browser to http://<pi-ip-address>:5000
To have SWAKES Print start automatically on boot:
sudo nano /etc/systemd/system/label_service.service[Unit]
Description=SWAKES Print Label Service
After=network.target
[Service]
WorkingDirectory=/home/pi/swakes-print
ExecStart=/home/pi/swakes-print/venv/bin/python3 app.py
Restart=always
User=pi
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable label_service
sudo systemctl start label_serviceTo enable the Restart Service button in the Settings panel:
sudo nano /etc/sudoers.d/label_serviceAdd:
pi ALL=(ALL) NOPASSWD: /bin/systemctl restart label_service
swakes-print/
├── app.py # Flask application and API routes
├── printer_backend.py # Brother QL printer interface
├── config.json # Printer and label configuration
├── favourites.json # Saved label favourites (auto-created)
├── settings.json # App settings (auto-created)
├── print_history.json # Print history log (auto-created)
├── templates/
│ └── index.html # Main UI (single-page)
├── static/
│ ├── styles.css # Dark navy theme
│ └── logo.png # App logo
├── fonts/ # Uploaded custom fonts (auto-created)
├── uploads/ # Temporary image uploads (auto-created)
└── templates_data/ # Label template definitions
├── address_label.json
└── food_label.json
| Key | Description | Default |
|---|---|---|
printer.model |
Brother printer model | QL-570 |
printer.device |
USB or network device string | usb://0x04f9:0x2042 |
printer.backend |
Print backend (pyusb, network, linux_kernel) |
pyusb |
label.default_size |
Default label size | 62x29 |
label.supported_labels |
Available sizes in the UI | ["62x29",...] |
label.default_font |
Font used if none selected | DejaVuSans.ttf |
label.default_font_size |
Default text size in points | 32 |
| Size | Pixels (W × H) | Description |
|---|---|---|
62x29 |
696 × 271 | Standard address label |
29x90 |
306 × 991 | Tall narrow label |
62x100 |
696 × 1109 | Large square label |
12 |
142 × 500 | Thin tape |
29 |
306 × 500 | Narrow label |
Wide format models (QL-1050, QL-1060N, QL-1100+) support additional 102mm label widths. Add the relevant sizes to
supported_labelsinconfig.jsonto use them.
Printer shows Offline
- Check the USB cable is connected and the printer is powered on
- Verify the USB IDs in
config.jsonmatchlsusboutput - Check udev rules are applied:
sudo udevadm trigger - For network printers, confirm the IP address and that port 9100 is reachable
Permission denied on USB
- Run
ls -la /dev/bus/usb/...and check the device permissions - Ensure the udev rule is in place and the user is in the correct group
Font not appearing in dropdown after upload
- Font upload lives in Settings → Fonts
- After uploading, the font appears immediately in the dropdown without a page refresh
Restart button does nothing
- Ensure the sudoers rule is in place (see above)
- Check the service name matches exactly:
label_service
Print history not recording
- Ensure the service has write permission to the working directory
- Check the service logs:
sudo journalctl -u label_service -n 50
Changed printer model but nothing happened
- After saving in Settings → Printer, go to Settings → System and restart the service
MIT — free to use, modify, and distribute. See LICENSE for details.
Built with ❤️ for the Raspberry Pi community




