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 src/backend/InvenTree/machine/machine_types/label_printer.py
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
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'), ColorEnum.success
    UNKNOWN = 101, _('Unknown'), ColorEnum.secondary
    PRINTING = 110, _('Printing'), ColorEnum.primary
    NO_MEDIA = 301, _('No media'), ColorEnum.warning
    PAPER_JAM = 302, _('Paper jam'), ColorEnum.warning
    DISCONNECTED = 400, _('Disconnected'), ColorEnum.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 src/backend/InvenTree/machine/machine_types/label_printer.py
 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
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: models.Model,
        **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)

        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[models.Model],
        **kwargs,
    ) -> Union[JsonResponse, None]:
        """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)

        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, **kwargs)

    def get_printers(
        self, label: LabelTemplate, items: QuerySet, **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: models.Model, **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 = self._get_dummy_request()
        return self.machine_plugin.render_to_pdf(label, item, request, **kwargs)

    def render_to_pdf_data(
        self, label: LabelTemplate, item: models.Model, **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
        """
        return self.render_to_pdf(label, item, **kwargs)

    def render_to_html(self, label: LabelTemplate, item: models.Model, **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 = self._get_dummy_request()
        return self.machine_plugin.render_to_html(label, item, request, **kwargs)

    def render_to_png(
        self, label: LabelTemplate, item: models.Model, **kwargs
    ) -> Union[Image, None]:
        """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

        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)
        """
        request = self._get_dummy_request()
        return self.machine_plugin.render_to_png(label, item, request, **kwargs)

    def _get_dummy_request(self):
        """Return a dummy request object to it work with legacy code.

        Note: this is a private method and can be removed at anytime
        """
        r = HttpRequest()
        r.META['SERVER_PORT'] = '80'
        r.META['SERVER_NAME'] = 'localhost'
        r.user = AnonymousUser()

        return r

    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 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 src/backend/InvenTree/machine/machine_types/label_printer.py
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
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, **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 Model

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

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 src/backend/InvenTree/machine/machine_types/label_printer.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
def print_label(
    self,
    machine: 'LabelPrinterMachine',
    label: LabelTemplate,
    item: models.Model,
    **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)

    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, **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[Model]

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

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[JsonResponse, None]

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 src/backend/InvenTree/machine/machine_types/label_printer.py
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
def print_labels(
    self,
    machine: 'LabelPrinterMachine',
    label: LabelTemplate,
    items: QuerySet[models.Model],
    **kwargs,
) -> Union[JsonResponse, None]:
    """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)

    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, **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

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 src/backend/InvenTree/machine/machine_types/label_printer.py
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
def get_printers(
    self, label: LabelTemplate, items: QuerySet, **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 src/backend/InvenTree/machine/machine_types/label_printer.py
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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, **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 Model

The item to render the label with

required
Source code in src/backend/InvenTree/machine/machine_types/label_printer.py
123
124
125
126
127
128
129
130
131
132
133
def render_to_pdf(
    self, label: LabelTemplate, item: models.Model, **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 = self._get_dummy_request()
    return self.machine_plugin.render_to_pdf(label, item, request, **kwargs)

render_to_pdf_data(label, item, **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 Model

The item to render the label with

required
Source code in src/backend/InvenTree/machine/machine_types/label_printer.py
135
136
137
138
139
140
141
142
143
144
def render_to_pdf_data(
    self, label: LabelTemplate, item: models.Model, **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
    """
    return self.render_to_pdf(label, item, **kwargs)

render_to_html(label, item, **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 Model

The item to render the label with

required
Source code in src/backend/InvenTree/machine/machine_types/label_printer.py
146
147
148
149
150
151
152
153
154
def render_to_html(self, label: LabelTemplate, item: models.Model, **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 = self._get_dummy_request()
    return self.machine_plugin.render_to_html(label, item, request, **kwargs)

render_to_png(label, item, **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 Model

The item to render the label with

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 src/backend/InvenTree/machine/machine_types/label_printer.py
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
def render_to_png(
    self, label: LabelTemplate, item: models.Model, **kwargs
) -> Union[Image, None]:
    """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

    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)
    """
    request = self._get_dummy_request()
    return self.machine_plugin.render_to_png(label, item, request, **kwargs)