Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/hxmz-axfn07/qr-printing-sfw/llms.txt

Use this file to discover all available pages before exploring further.

QR Print Station uses two configuration files with clearly separated responsibilities. .env (at the project root) controls infrastructure-level settings: the TCP port, database credentials, the admin secret token, and the optional print command. config.yml controls everything the customer sees: shop name and contact info, on-screen instructions, pricing rules, paper size options, and theme colors. Both files are read at startup; .env values are also re-read on each QR refresh cycle so that a PUBLIC_URL change takes effect without restarting the process.

Environment Variables

These variables are read from .env in the project root. Any variable can also be set as a real OS environment variable — OS environment takes precedence over the file.
ADMIN_TOKEN is the only thing standing between the public internet and your order data and uploaded files. The default value change-this-secret-token must be replaced with a long, randomly generated string before you run the server on any network. Treat it like a password — do not commit it to version control or share it in plaintext.
PORT
integer
default:"8000"
TCP port the ThreadingHTTPServer binds to on all interfaces (0.0.0.0). Change this if port 8000 is already in use on your machine. You will need to reflect the new port in any firewall rules or reverse-proxy configuration.
PUBLIC_URL
string
Optional fully-qualified public URL (e.g. an ngrok tunnel like https://abc.ngrok-free.app). When set, the QR code encodes this URL as its target instead of the local IP address and port. Leave blank for LAN-only deployments. The value is stripped of a trailing slash and, if it does not already end with /upload, the upload path is appended automatically.
QR_REFRESH_SECONDS
integer
default:"5"
How often, in seconds, the background daemon thread re-evaluates whether the QR code PNG needs to be regenerated. The thread compares the current upload URL (derived from PUBLIC_URL or the local IP) against the last URL written to qr-codes/.last_url. If they differ, or if qr-codes/upload.png does not exist, the PNG is regenerated. Lower values make PUBLIC_URL changes take effect faster at the cost of slightly more disk I/O.
ADMIN_TOKEN
string
required
Secret token that forms the admin dashboard URL: http://<host>:<port>/admin/<ADMIN_TOKEN>. The server returns 404 for any /admin/ path that does not match this token exactly, giving no indication that a dashboard exists. The token is also accepted for API calls as the X-Admin-Token request header or as the ?token= query parameter.
MYSQL_HOST
string
default:"127.0.0.1"
Hostname or IP address of the MySQL or MariaDB server. Use 127.0.0.1 rather than localhost to ensure a TCP connection (rather than a Unix socket) when running both services on the same machine.
MYSQL_PORT
integer
default:"3306"
TCP port of the MySQL server. Change this only if your database listens on a non-standard port.
MYSQL_USER
string
default:"qr_print_user"
MySQL user account. The bundled server/schema.sql creates this user with GRANT ALL PRIVILEGES on the qr_printing database.
MYSQL_PASSWORD
string
Password for MYSQL_USER. Must match the password set when the database was created. The default in server/schema.sql is change_me — update both the schema and this variable together.
MYSQL_DATABASE
string
default:"qr_printing"
Name of the MySQL database. The schema file creates this database with utf8mb4 character set and utf8mb4_unicode_ci collation.
PRINT_COMMAND
string
Optional shell command executed when staff trigger printing from the admin dashboard. The command is run with subprocess.run(..., shell=True) for each document in the order. Leave blank to skip automatic printing and handle jobs manually. See PRINT_COMMAND Placeholders below for available substitution tokens.

config.yml

config.yml lives at the project root and controls shop content, pricing, and UI options. All values have in-code defaults so the server starts even without the file, but customising it is essential for a real deployment.
shop:
  # Display name shown on the customer-facing upload page and success screen.
  name: QR Print Station

  # Street address or location description shown to customers.
  address: Local print shop

  # Contact phone number shown on the upload page.
  phone: "+91 XXXXX XXXXX"

  # Ordered list of instructions shown to customers before they start uploading.
  instructions:
    - Scan QR.
    - Add one or more files.
    - Choose print settings for each document.
    - Submit order and wait for staff review.

  # Descriptive text shown in the file picker explaining accepted formats.
  supported_file_types:
    - PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, images, text files, and other common print files

  # Maximum size in megabytes for a single uploaded file.
  # The server enforces this limit server-side; default is 50.
  max_upload_mb: 50

theme:
  # Primary accent color (buttons, highlights). Hex string.
  accent: "#166a5b"

  # Secondary accent color (badges, secondary highlights). Hex string.
  accent_2: "#e2b23c"

  # Page background color. Hex string.
  background: "#f6f7f2"

# Pricing rules. Each entry defines the price per page for one combination of
# paper size, color mode, and print style. The pricing table is seeded into
# MySQL on first startup; subsequent changes to config.yml require a database
# update or re-seeding. The admin dashboard can also update pricing via the
# settings table at runtime.
pricing:
  - label: A4 B/W Single Side       # Human-readable label shown on the upload form
    paper_size: A4                   # Must match a value in options.paper_sizes
    color_mode: bw                   # "bw" or "color"
    print_style: single              # "single" or "double"
    price_per_page: 2

  - label: A4 B/W Double Side
    paper_size: A4
    color_mode: bw
    print_style: double
    price_per_page: 1.5

  - label: A4 Color Single Side
    paper_size: A4
    color_mode: color
    print_style: single
    price_per_page: 10

  - label: A4 Color Double Side
    paper_size: A4
    color_mode: color
    print_style: double
    price_per_page: 8

options:
  # List of paper size strings shown in the per-document size selector.
  paper_sizes:
    - A4
    - A3
    - Letter

  # Map of color mode keys to display labels used in the upload form.
  # Keys must be "bw" and/or "color" — these are stored verbatim in the database.
  color_modes:
    bw: Black & white
    color: Color

  # Map of print style keys to display labels used in the upload form.
  # Keys must be "single" and/or "double" — stored verbatim in the database.
  print_styles:
    single: Single side
    double: Double side

Configuration precedence

At runtime, config.yml values are merged with in-code defaults (file wins over defaults). The settings MySQL table is then applied on top (database wins over file), allowing staff to update shop name, address, phone, file size limit, and theme accent color from the admin dashboard without touching the file. The pricing table similarly overrides config.yml pricing once rows exist in the database.
When PRINT_COMMAND is set, the server calls your shell command once per document when staff click Print in the admin dashboard. The following placeholders are substituted with the actual per-document values at print time:
PlaceholderTypeDescription
{file}string (path)Absolute path to the uploaded file on disk, inside uploads/
{copies}integerNumber of copies requested by the customer (1–99)
{paper}stringPaper size value from options.paper_sizes (e.g. A4, A3, Letter)
{color}stringColor mode key: bw or color
{style}stringPrint style key: single or double
Example using the standard CUPS lp command:
PRINT_COMMAND=lp -n {copies} -o media={paper} "{file}"
If the command exits with a non-zero return code, the order is automatically transitioned to the failed status and the stderr output is stored as the failure reason, visible in the admin dashboard.

Build docs developers (and LLMs) love