A secure, zero-footprint local printing client for Odoo. This client connects to your Odoo instance via WebSockets, listens for print jobs on the Odoo Bus, and pipes documents directly to your local Linux print spooler (CUPS) without ever saving files to disk.
- Zero Footprint (In-Memory Printing): Documents are decoded in RAM and piped directly to
stdinof the OS print command. No temporary files are created, ensuring maximum data privacy (GDPR compliant). - PDF and ZPL support: Handles standard PDF documents as well as ZPL label files (sent raw to label printers such as Zebra).
- High Security:
- Validates magic bytes:
%PDFfor PDF files,^XAfor ZPL files. - Uses strict Base64 decoding.
- Prevents OS Command Injection by executing subprocesses safely without
shell=True.
- Validates magic bytes:
- Configurable Channel: Subscribe to any Odoo Bus channel via environment variable or CLI argument, allowing multiple clients to listen on different channels simultaneously.
- Firewall Friendly: Uses WebSockets to initiate an outbound connection to Odoo. No inbound ports need to be opened on the client's local network.
- Environment Variables (.env): Securely manage Odoo credentials without hardcoding them.
- Linux OS (Ubuntu, Debian, etc.)
- CUPS (Common UNIX Printing System) installed and running. The
lpcommand must be available in the system path. - Python 3.7+
pip install odoo-print-client- Clone the repository and navigate into it:
git clone https://github.com/forgeflow/odoo-print-client.git cd odoo-print-client - (Optional but recommended) Create and activate a virtual environment:
python3 -m venv venv source venv/bin/activate - Install the package:
pip install -e .
Create a .env file in the directory from which you will run the client:
ODOO_URL=http://localhost:8069
ODOO_DB=your_database_name
ODOO_USER=print_service_user
ODOO_PASSWORD=your_super_secure_password
ODOO_CHANNEL=your_odoo_channelSecure the file so only the owner can read it:
chmod 600 .envNote: It is highly recommended to create a dedicated Odoo user (e.g.,
print_service) with minimal access rights solely for authenticating this client, rather than using the admin account.
Once installed and configured, run:
odoo-printerThe client loads credentials from the .env file, authenticates via JSON-RPC, establishes the WebSocket connection, and listens for incoming print jobs on the configured channel.
All options can be overridden via command-line arguments:
odoo-printer \
--url "https://odoo.example.com" \
--db "prod" \
--user "print_service" \
--password "secret" \
--channel "printer_office_1"| Argument | Env variable | Description |
|---|---|---|
--url |
ODOO_URL |
Odoo base URL |
--db |
ODOO_DB |
Odoo database name |
--user |
ODOO_USER |
Odoo username |
--password |
ODOO_PASSWORD |
Odoo password |
--channel |
ODOO_CHANNEL |
Odoo Bus channel to subscribe to |
To serve multiple printers or locations, run one instance per channel with different .env files or by passing --channel directly:
odoo-printer --channel "printer_warehouse" &
odoo-printer --channel "printer_office" &This client expects a specific JSON payload sent through bus.bus on the configured channel. You will need a custom Odoo module to intercept the print action and send the payload.
{
"type": "print_job",
"payload": {
"printer_name": "Name_of_CUPS_Printer",
"file_type": "pdf",
"file_data": "JVBERi0xLjQKJcOkw7zDts..."
}
}| Field | Required | Values | Description |
|---|---|---|---|
printer_name |
No | Any CUPS printer name | Omit to use the system default printer |
file_type |
No | pdf (default), zpl |
Determines how the file is processed |
file_data |
Yes | Base64 string | Strictly Base64-encoded file content |
Validated against the %PDF magic bytes and sent to CUPS via lp.
Validated against the ^XA ZPL start-of-label marker and sent to CUPS via lp -o raw, bypassing raster processing so the raw ZPL stream reaches the label printer directly.