Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I send print jobs directly from a python program to the IP address of a CUPS print server?

I have two linux computers with fixed IP addresses:

  1. A print server, whereby the connected printer is shared via CUPS.
    (The server has the IP address "192.168.1.2" and the printer is called "test_printer".)
  2. A computer, on which a python application is running, that should be able to use this print server.

Unfortunately, the printer propagation via CUPS seems not to work reliably (possibly due to the structure of the network).

Can I send print jobs directly from a python program to the CUPS print server?
If so, can you please provide a small example?

In theory, I would just send correctly formatted data to the IP address + port, but I didn't get it to work ...


Here are the approaches I have found so far and my problems with them:

  • command 'lpr'

    import subprocess
    
    lpr = subprocess.Popen("usr/bin/lpr", stdin=subprocess.PIPE)        # on some distros the command is 'lp'
    lpr.stdin.write("hello world\n")
    lpr.stdin.close()
    

    Relies on the printer propagation via CUPS.


  • python module pycups

    import cups
    
    with open("/home/user/Documents/some.txt", "w") as f:
        f.write("hello world\n")
    
    conn = cups.Connection()
    conn.printFile("test_printer", "/home/user/Documents/some.txt", "some_title", {})
    

    Before I can use a printer, I'll have to add it first, which in turn relies on the propagation via CUPS.
    Also I didn't get conn.addPrinter() to work.


  • python module python-escpos / python-printer-escpos

    import escpos.printer
    
    p = escpos.printer.Network("192.168.1.2", port=631)        # port 9100 seems not to work.
    p.text("hello world\n")
    p.close()
    

    Probably the most promising approach ... unfortunately it doesn't print anything and throws an exception on closing.

    # The traceback was produced in the interactive shell.
    Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
        File "/home/user/.local/lib/python3.6/site-package/escpos/printer.py", line 214, in close
            self.device.shutdown(socket.SHUT_RDWR)
    OSError: [Errno 107] Transport endpoint is not connected
    


  • python module pkipplib / pyipptool
    Unfortunately, there seems not to be a working python3 library that implements the Internet Printing Protocol (IPP) in 2018.

I use python 3.6.7.
The print server uses CUPS 2.2.1.

like image 390
AFoeee Avatar asked Dec 05 '18 18:12

AFoeee


People also ask

How do I assign an IP address to a print server?

you can not change the printer ip from print server. you have to change the Printer IP manually at printer end or access printer on browser the change IP...

Does a print server have an IP address?

The IP address of the printer server will most likely be the same as the IP address of the router. To find your router's IP address, open up a command prompt from Windows' Start menu Search box. Type ipconfig and hit Enter.

How do printers connect to CUPS?

The process to access CUPS is the same: Ensure CUPS is installed, open a network, and navigate to localhost:631 . Once you've accessed the CUPS web interface, select the Administration tab. Click the Find New Printers button in the Printers section, and then add the shared printer to your network.


1 Answers

Not being a Python programmer, I cannot provide any sample code.

But I can give you some other hints:

  1. Your assumption, that "in theory, [....] just send correctly formatted data to the IP address + port" is wrong.

    If you send something, you have to "talk IPP" to the CUPS server (yes, via the IP address + port 631). But just sending a file is so much less than talking IPP.

    Else, you could use 'netcat IPaddress port-no < filename' to print to any CUPS queue (which would be a huge security issue).

    So you HAVE to use some IPP-capable library, if you want to integrate your program with IPP/CUPS

  2. One alternative could be that you let your program do the "IPP talk to CUPS" by a CLI tool which is capable of doing so.

    Have a look at the ippsample code of the Printer Working Group (PWG) which designed the IPP. That is in "beta" still but already fully usable. All its binaries are command line (CLI) utilities:

    • It provides the ippfind helper tool. If you run it without any parameters, it will print a list of available IPP Services (print servers and/or printer devices) by printing their respective IPP URIs.

    • It provides an ippserver command line, which can start up a fully-fledged, you guessed it, IPP Server exposing any feature you want.

    • Then there is ipptool included as an IPP Client. You could run 'ipptool -f myprintfile -t -v ipp://cupsserver/printers/test_printer print-job.test' to send "myprintfile" to the queue "test_printer" on "cupsserver" (given with example IPP URI ipp://cupsserver/printers/test_printer) and watch it talk IPP to CUPS while it does so.

  See also my ASCIIcast "[TUTORIAL] IPP Sample Software (made with an AppImage)" here. {https://asciinema.org/a/155588 }. Hint: if it plays too fast to follow and understand the screens in time, use the 'pause' button, read at your own speed, then resume playing.

like image 79
Kurt Pfeifle Avatar answered Sep 24 '22 16:09

Kurt Pfeifle