Skip to content

Label Printer

Label printer

Label printer machines can directly print labels for various items in InvenTree. They replace standard LabelPrintingMixin plugins that are used to connect to physical printers. Using machines rather than a standard LabelPrintingMixin plugin has the advantage that machines can be created multiple times using different settings but the same driver. That way multiple label printers of the same brand can be connected.

Writing your own printing driver

Take a look at the most basic required code for a driver in this example. Next either implement the print_label or print_labels function.

Label printer status

There are a couple of predefined status codes for label printers. By default the UNKNOWN status code is set for each machine, but they can be changed at any time by the driver. For more info about status code see Machine status codes.

Attributes:

Name Type Description
CONNECTED

The printer is connected and ready to print

UNKNOWN

The printer status is unknown (e.g. there is no active connection to the printer)

PRINTING

The printer is currently printing a label

NO_MEDIA

The printer is out of media (e.g. the label spool is empty)

DISCONNECTED

The driver cannot establish a connection to the printer

Source code in InvenTree/machine/machine_types/label_printer.py
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
class LabelPrinterStatus(MachineStatus):
    """Label printer status codes.

    Attributes:
        CONNECTED: The printer is connected and ready to print
        UNKNOWN: The printer status is unknown (e.g. there is no active connection to the printer)
        PRINTING: The printer is currently printing a label
        NO_MEDIA: The printer is out of media (e.g. the label spool is empty)
        DISCONNECTED: The driver cannot establish a connection to the printer
    """

    CONNECTED = 100, _('Connected'), 'success'
    UNKNOWN = 101, _('Unknown'), 'secondary'
    PRINTING = 110, _('Printing'), 'primary'
    NO_MEDIA = 301, _('No media'), 'warning'
    DISCONNECTED = 400, _('Disconnected'), 'danger'

LabelPrintingDriver API

Base driver for label printer machines.

Attributes:

Name Type Description
USE_BACKGROUND_WORKER bool

If True, the print_label() and print_labels() methods will be run in a background worker (default: True)

Source code in InvenTree/machine/machine_types/label_printer.py
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
class LabelPrinterBaseDriver(BaseDriver):
    """Base driver for label printer machines.

    Attributes:
        USE_BACKGROUND_WORKER (bool): If True, the `print_label()` and `print_labels()` methods will be run in a background worker (default: True)
    """

    machine_type = 'label-printer'

    USE_BACKGROUND_WORKER = True

    def print_label(
        self,
        machine: 'LabelPrinterMachine',
        label: LabelTemplate,
        item: LabelItemType,
        request: Request,
        **kwargs,
    ) -> None:
        """Print a single label with the provided template and item.

        Arguments:
            machine: The LabelPrintingMachine instance that should be used for printing
            label: The LabelTemplate object to use for printing
            item: The database item to print (e.g. StockItem instance)
            request: The HTTP request object which triggered this print job

        Keyword Arguments:
            printing_options (dict): The printing options set for this print job defined in the PrintingOptionsSerializer
                by default the following options are available:
                - copies: number of copies to print for the label

        Note that the supplied args/kwargs may be different if the driver overrides the print_labels() method.
        """

    def print_labels(
        self,
        machine: 'LabelPrinterMachine',
        label: LabelTemplate,
        items: QuerySet[LabelItemType],
        request: Request,
        **kwargs,
    ) -> Union[None, JsonResponse]:
        """Print one or more labels with the provided template and items.

        Arguments:
            machine: The LabelPrintingMachine instance that should be used for printing
            label: The LabelTemplate object to use for printing
            items: The list of database items to print (e.g. StockItem instances)
            request: The HTTP request object which triggered this print job

        Keyword Arguments:
            printing_options (dict): The printing options set for this print job defined in the PrintingOptionsSerializer
                by default the following options are available:
                - copies: number of copies to print for each label

        Returns:
            If `USE_BACKGROUND_WORKER=False`, a JsonResponse object which indicates outcome to the user, otherwise None

        The default implementation simply calls print_label() for each label, producing multiple single label output "jobs"
        but this can be overridden by the particular driver.
        """
        for item in items:
            self.print_label(machine, label, item, request, **kwargs)

    def get_printers(
        self, label: LabelTemplate, items: QuerySet[LabelItemType], **kwargs
    ) -> list['LabelPrinterMachine']:
        """Get all printers that would be available to print this job.

        By default all printers that are initialized using this driver are returned.

        Arguments:
            label: The LabelTemplate object to use for printing
            items: The lost of database items to print (e.g. StockItem instances)

        Keyword Arguments:
            request (Request): The django request used to make the get printers request
        """
        return cast(list['LabelPrinterMachine'], self.get_machines())

    def get_printing_options_serializer(
        self, request: Request, *args, **kwargs
    ) -> 'LabelPrinterBaseDriver.PrintingOptionsSerializer':
        """Return a serializer class instance with dynamic printing options.

        Arguments:
            request: The request made to print a label or interfering the available serializer fields via an OPTIONS request

        Note:
            `*args`, `**kwargs` needs to be passed to the serializer instance

        Returns:
            A class instance of a DRF serializer class, by default this an instance of self.PrintingOptionsSerializer using the *args, **kwargs if existing for this driver
        """
        return self.PrintingOptionsSerializer(*args, **kwargs)  # type: ignore

    # --- helper functions
    @property
    def machine_plugin(self) -> LabelPrintingMixin:
        """Returns the builtin machine label printing plugin that manages printing through machines."""
        plg = plg_registry.get_plugin('inventreelabelmachine')
        return cast(LabelPrintingMixin, plg)

    def render_to_pdf(
        self, label: LabelTemplate, item: LabelItemType, request: Request, **kwargs
    ) -> HttpResponse:
        """Helper method to render a label to PDF format for a specific item.

        Arguments:
            label: The LabelTemplate object to render
            item: The item to render the label with
            request: The HTTP request object which triggered this print job
        """
        label.object_to_print = item
        response = self.machine_plugin.render_to_pdf(label, request, **kwargs)
        label.object_to_print = None
        return response

    def render_to_pdf_data(
        self, label: LabelTemplate, item: LabelItemType, request: Request, **kwargs
    ) -> bytes:
        """Helper method to render a label to PDF and return it as bytes for a specific item.

        Arguments:
            label: The LabelTemplate object to render
            item: The item to render the label with
            request: The HTTP request object which triggered this print job
        """
        return (
            self.render_to_pdf(label, item, request, **kwargs)
            .get_document()  # type: ignore
            .write_pdf()
        )

    def render_to_html(
        self, label: LabelTemplate, item: LabelItemType, request: Request, **kwargs
    ) -> str:
        """Helper method to render a label to HTML format for a specific item.

        Arguments:
            label: The LabelTemplate object to render
            item: The item to render the label with
            request: The HTTP request object which triggered this print job
        """
        label.object_to_print = item
        html = self.machine_plugin.render_to_html(label, request, **kwargs)
        label.object_to_print = None
        return html

    def render_to_png(
        self, label: LabelTemplate, item: LabelItemType, request: Request, **kwargs
    ) -> Image:
        """Helper method to render a label to PNG format for a specific item.

        Arguments:
            label: The LabelTemplate object to render
            item: The item to render the label with
            request: The HTTP request object which triggered this print job

        Keyword Arguments:
            pdf_data (bytes): The pdf document as bytes (optional)
            dpi (int): The dpi used to render the image (optional)
            use_cairo (bool): Whether to use the pdftocairo backend for rendering which provides better results in tests,
                see [#6488](https://github.com/inventree/InvenTree/pull/6488) for details. If False, pdftoppm is used (default: True)
            pdf2image_kwargs (dict): Additional keyword arguments to pass to the
                [`pdf2image.convert_from_bytes`](https://pdf2image.readthedocs.io/en/latest/reference.html#pdf2image.pdf2image.convert_from_bytes) method (optional)
        """
        label.object_to_print = item
        png = self.machine_plugin.render_to_png(label, request, **kwargs)
        label.object_to_print = None
        return png

    required_overrides = [[print_label, print_labels]]

    class PrintingOptionsSerializer(serializers.Serializer):
        """Printing options serializer that implements common options.

        This can be overridden by the driver to implement custom options, but the driver should always extend this class.

        Example:
            This example shows how to extend the default serializer and add a new option:
            ```py
            class MyDriver(LabelPrinterBaseDriver):
                # ...

                class PrintingOptionsSerializer(LabelPrinterBaseDriver.PrintingOptionsSerializer):
                    auto_cut = serializers.BooleanField(
                        default=True,
                        label=_('Auto cut'),
                        help_text=_('Automatically cut the label after printing'),
                    )
            ```
        """

        copies = serializers.IntegerField(
            default=1,
            label=_('Copies'),
            help_text=_('Number of copies to print for each label'),
        )

machine_plugin: LabelPrintingMixin property

Returns the builtin machine label printing plugin that manages printing through machines.

PrintingOptionsSerializer

Printing options serializer that implements common options.

This can be overridden by the driver to implement custom options, but the driver should always extend this class.

Example

This example shows how to extend the default serializer and add a new option:

class MyDriver(LabelPrinterBaseDriver):
    # ...

    class PrintingOptionsSerializer(LabelPrinterBaseDriver.PrintingOptionsSerializer):
        auto_cut = serializers.BooleanField(
            default=True,
            label=_('Auto cut'),
            help_text=_('Automatically cut the label after printing'),
        )

Source code in InvenTree/machine/machine_types/label_printer.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
class PrintingOptionsSerializer(serializers.Serializer):
    """Printing options serializer that implements common options.

    This can be overridden by the driver to implement custom options, but the driver should always extend this class.

    Example:
        This example shows how to extend the default serializer and add a new option:
        ```py
        class MyDriver(LabelPrinterBaseDriver):
            # ...

            class PrintingOptionsSerializer(LabelPrinterBaseDriver.PrintingOptionsSerializer):
                auto_cut = serializers.BooleanField(
                    default=True,
                    label=_('Auto cut'),
                    help_text=_('Automatically cut the label after printing'),
                )
        ```
    """

    copies = serializers.IntegerField(
        default=1,
        label=_('Copies'),
        help_text=_('Number of copies to print for each label'),
    )

print_label(machine, label, item, request, **kwargs)

Print a single label with the provided template and item.

Parameters:

Name Type Description Default
machine LabelPrinterMachine

The LabelPrintingMachine instance that should be used for printing

required
label LabelTemplate

The LabelTemplate object to use for printing

required
item LabelItemType

The database item to print (e.g. StockItem instance)

required
request Request

The HTTP request object which triggered this print job

required

Other Parameters:

Name Type Description
printing_options dict

The printing options set for this print job defined in the PrintingOptionsSerializer by default the following options are available: - copies: number of copies to print for the label

Note that the supplied args/kwargs may be different if the driver overrides the print_labels() method.

Source code in InvenTree/machine/machine_types/label_printer.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
def print_label(
    self,
    machine: 'LabelPrinterMachine',
    label: LabelTemplate,
    item: LabelItemType,
    request: Request,
    **kwargs,
) -> None:
    """Print a single label with the provided template and item.

    Arguments:
        machine: The LabelPrintingMachine instance that should be used for printing
        label: The LabelTemplate object to use for printing
        item: The database item to print (e.g. StockItem instance)
        request: The HTTP request object which triggered this print job

    Keyword Arguments:
        printing_options (dict): The printing options set for this print job defined in the PrintingOptionsSerializer
            by default the following options are available:
            - copies: number of copies to print for the label

    Note that the supplied args/kwargs may be different if the driver overrides the print_labels() method.
    """

print_labels(machine, label, items, request, **kwargs)

Print one or more labels with the provided template and items.

Parameters:

Name Type Description Default
machine LabelPrinterMachine

The LabelPrintingMachine instance that should be used for printing

required
label LabelTemplate

The LabelTemplate object to use for printing

required
items QuerySet[LabelItemType]

The list of database items to print (e.g. StockItem instances)

required
request Request

The HTTP request object which triggered this print job

required

Other Parameters:

Name Type Description
printing_options dict

The printing options set for this print job defined in the PrintingOptionsSerializer by default the following options are available: - copies: number of copies to print for each label

Returns:

Type Description
Union[None, JsonResponse]

If USE_BACKGROUND_WORKER=False, a JsonResponse object which indicates outcome to the user, otherwise None

The default implementation simply calls print_label() for each label, producing multiple single label output "jobs" but this can be overridden by the particular driver.

Source code in InvenTree/machine/machine_types/label_printer.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
def print_labels(
    self,
    machine: 'LabelPrinterMachine',
    label: LabelTemplate,
    items: QuerySet[LabelItemType],
    request: Request,
    **kwargs,
) -> Union[None, JsonResponse]:
    """Print one or more labels with the provided template and items.

    Arguments:
        machine: The LabelPrintingMachine instance that should be used for printing
        label: The LabelTemplate object to use for printing
        items: The list of database items to print (e.g. StockItem instances)
        request: The HTTP request object which triggered this print job

    Keyword Arguments:
        printing_options (dict): The printing options set for this print job defined in the PrintingOptionsSerializer
            by default the following options are available:
            - copies: number of copies to print for each label

    Returns:
        If `USE_BACKGROUND_WORKER=False`, a JsonResponse object which indicates outcome to the user, otherwise None

    The default implementation simply calls print_label() for each label, producing multiple single label output "jobs"
    but this can be overridden by the particular driver.
    """
    for item in items:
        self.print_label(machine, label, item, request, **kwargs)

get_printers(label, items, **kwargs)

Get all printers that would be available to print this job.

By default all printers that are initialized using this driver are returned.

Parameters:

Name Type Description Default
label LabelTemplate

The LabelTemplate object to use for printing

required
items QuerySet[LabelItemType]

The lost of database items to print (e.g. StockItem instances)

required

Other Parameters:

Name Type Description
request Request

The django request used to make the get printers request

Source code in InvenTree/machine/machine_types/label_printer.py
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
def get_printers(
    self, label: LabelTemplate, items: QuerySet[LabelItemType], **kwargs
) -> list['LabelPrinterMachine']:
    """Get all printers that would be available to print this job.

    By default all printers that are initialized using this driver are returned.

    Arguments:
        label: The LabelTemplate object to use for printing
        items: The lost of database items to print (e.g. StockItem instances)

    Keyword Arguments:
        request (Request): The django request used to make the get printers request
    """
    return cast(list['LabelPrinterMachine'], self.get_machines())

get_printing_options_serializer(request, *args, **kwargs)

Return a serializer class instance with dynamic printing options.

Parameters:

Name Type Description Default
request Request

The request made to print a label or interfering the available serializer fields via an OPTIONS request

required
Note

*args, **kwargs needs to be passed to the serializer instance

Returns:

Type Description
PrintingOptionsSerializer

A class instance of a DRF serializer class, by default this an instance of self.PrintingOptionsSerializer using the args, *kwargs if existing for this driver

Source code in InvenTree/machine/machine_types/label_printer.py
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
def get_printing_options_serializer(
    self, request: Request, *args, **kwargs
) -> 'LabelPrinterBaseDriver.PrintingOptionsSerializer':
    """Return a serializer class instance with dynamic printing options.

    Arguments:
        request: The request made to print a label or interfering the available serializer fields via an OPTIONS request

    Note:
        `*args`, `**kwargs` needs to be passed to the serializer instance

    Returns:
        A class instance of a DRF serializer class, by default this an instance of self.PrintingOptionsSerializer using the *args, **kwargs if existing for this driver
    """
    return self.PrintingOptionsSerializer(*args, **kwargs)  # type: ignore

render_to_pdf(label, item, request, **kwargs)

Helper method to render a label to PDF format for a specific item.

Parameters:

Name Type Description Default
label LabelTemplate

The LabelTemplate object to render

required
item LabelItemType

The item to render the label with

required
request Request

The HTTP request object which triggered this print job

required
Source code in InvenTree/machine/machine_types/label_printer.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
def render_to_pdf(
    self, label: LabelTemplate, item: LabelItemType, request: Request, **kwargs
) -> HttpResponse:
    """Helper method to render a label to PDF format for a specific item.

    Arguments:
        label: The LabelTemplate object to render
        item: The item to render the label with
        request: The HTTP request object which triggered this print job
    """
    label.object_to_print = item
    response = self.machine_plugin.render_to_pdf(label, request, **kwargs)
    label.object_to_print = None
    return response

render_to_pdf_data(label, item, request, **kwargs)

Helper method to render a label to PDF and return it as bytes for a specific item.

Parameters:

Name Type Description Default
label LabelTemplate

The LabelTemplate object to render

required
item LabelItemType

The item to render the label with

required
request Request

The HTTP request object which triggered this print job

required
Source code in InvenTree/machine/machine_types/label_printer.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def render_to_pdf_data(
    self, label: LabelTemplate, item: LabelItemType, request: Request, **kwargs
) -> bytes:
    """Helper method to render a label to PDF and return it as bytes for a specific item.

    Arguments:
        label: The LabelTemplate object to render
        item: The item to render the label with
        request: The HTTP request object which triggered this print job
    """
    return (
        self.render_to_pdf(label, item, request, **kwargs)
        .get_document()  # type: ignore
        .write_pdf()
    )

render_to_html(label, item, request, **kwargs)

Helper method to render a label to HTML format for a specific item.

Parameters:

Name Type Description Default
label LabelTemplate

The LabelTemplate object to render

required
item LabelItemType

The item to render the label with

required
request Request

The HTTP request object which triggered this print job

required
Source code in InvenTree/machine/machine_types/label_printer.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
def render_to_html(
    self, label: LabelTemplate, item: LabelItemType, request: Request, **kwargs
) -> str:
    """Helper method to render a label to HTML format for a specific item.

    Arguments:
        label: The LabelTemplate object to render
        item: The item to render the label with
        request: The HTTP request object which triggered this print job
    """
    label.object_to_print = item
    html = self.machine_plugin.render_to_html(label, request, **kwargs)
    label.object_to_print = None
    return html

render_to_png(label, item, request, **kwargs)

Helper method to render a label to PNG format for a specific item.

Parameters:

Name Type Description Default
label LabelTemplate

The LabelTemplate object to render

required
item LabelItemType

The item to render the label with

required
request Request

The HTTP request object which triggered this print job

required

Other Parameters:

Name Type Description
pdf_data bytes

The pdf document as bytes (optional)

dpi int

The dpi used to render the image (optional)

use_cairo bool

Whether to use the pdftocairo backend for rendering which provides better results in tests, see #6488 for details. If False, pdftoppm is used (default: True)

pdf2image_kwargs dict

Additional keyword arguments to pass to the pdf2image.convert_from_bytes method (optional)

Source code in InvenTree/machine/machine_types/label_printer.py
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def render_to_png(
    self, label: LabelTemplate, item: LabelItemType, request: Request, **kwargs
) -> Image:
    """Helper method to render a label to PNG format for a specific item.

    Arguments:
        label: The LabelTemplate object to render
        item: The item to render the label with
        request: The HTTP request object which triggered this print job

    Keyword Arguments:
        pdf_data (bytes): The pdf document as bytes (optional)
        dpi (int): The dpi used to render the image (optional)
        use_cairo (bool): Whether to use the pdftocairo backend for rendering which provides better results in tests,
            see [#6488](https://github.com/inventree/InvenTree/pull/6488) for details. If False, pdftoppm is used (default: True)
        pdf2image_kwargs (dict): Additional keyword arguments to pass to the
            [`pdf2image.convert_from_bytes`](https://pdf2image.readthedocs.io/en/latest/reference.html#pdf2image.pdf2image.convert_from_bytes) method (optional)
    """
    label.object_to_print = item
    png = self.machine_plugin.render_to_png(label, request, **kwargs)
    label.object_to_print = None
    return png