Product SiteDocumentation Site

12.2. Taking a Screenshot

To perform operations involving sending and receiving data from the software running on top of a virtualisation driver, we need to use streams.
For this example, we assume that we have a domain named 'TestDomain' running on the QEMU virtualisation driver.

Example 12.8. Looking up the domain

import sys, libvirt
conn = None
try:
    conn = libvirt.open("qemu:///system")
except libvirt.libvirtError as e:
    print(repr(e), file=sys.stderr)
    exit(1)
domain = conn.lookupByName('TestDomain')
We then create a stream, and take a screenshot. The 'screenshot' method returns the type of image that the screenshot is taken as. Different virtualisation drivers may produce different types of images.

Example 12.9. Use stream to take screenshot

stream = conn.newStream()
imageType = domain.screenshot(stream,0)
As the function 'virStreamRecv' (backend for the stream object’s 'recvAll' function) is not always supported, we can listen to our stream on a loop, writing as we go and checking to see if there’s any more data left to read:

Example 12.10. Reading data from stream

file = "Screenshot of " + dom.name()
fileHandler = open(file, 'wb')
streamBytes = stream.recv(262120)
while streamBytes != b'':
    fileHandler.write(streamBytes)
    streamBytes = stream.recv(262120)
fileHandler.close()
print('Screenshot saved as type: ' + imageType)
Once done, we can open our file and see that we have a screenshot of the virtual machine’s desktop. Success! Remember to finish the stream and close the virtualisation driver connection afterwards.
Full code in the example below.

Example 12.11. Taking a Screenshot

# Example-11.py
import sys
import libvirt

domName = 'TestAppliance'

conn = None
try:
    conn = libvirt.open("qemu:///system")
except libvirt.libvirtError as e:
    print(repr(e), file=sys.stderr)
    exit(1)

dom = None
try:
    dom = conn.lookupByName(domName)
except libvirt.libvirtError as e:
    print(repr(e), file=sys.stderr)
    exit(1)

stream = conn.newStream()

# This function supports up to three arguments:
#   stream, screen number and flags.
# We do not need to supply anything for the flags argument.
# The screen number is the sequential number of the screen
#   we want to take a screenshot of.

imageType = domain.screenshot(stream,0)

file = "Screenshot of " + dom.name()
fileHandler = open(file, ’wb’)
streamBytes = stream.recv(262120)

while streamBytes != b’’:
    fileHandler.write(streamBytes)
    streamBytes = stream.recv(262120)
fileHandler.close()

print(’Screenshot saved as type:+ imageType)
stream.finish()

conn.close()
exit(0)