Mumble Server Ice Scripting with Python
Improve this pageThis guide demonstrates how you can get started with using the Ice scripting interface of the Mumble server. Effectively, it is a summary of the official docs tuned specifically to the Mumble use case.
Prerequisite for this to work is that you have enabled Ice in your server’s configuration.
Setup
First, you have to install the Ice package for Python via
pip install zeroc-ice
Additionally, you need the slice file that defines the Ice interface. Make sure you obtain the slice file that corresponds to the actual server
version you are using. You can find the relevant slice files on GitHub by checking out the branch corresponding to your release series (i.e. 1.5.x
for Mumble 1.5.x) and then locating the MumbleServer.ice
file under src/murmur/
. Note that the slice file for development versions of Mumble can
always be found on the master
branch. See also the list of branches in the GitHub repository.
The relevant slice file may also be part of your installation already but its exact install location can vary. Typically, it can be found under e.g.
/usr/local/share/mumble-server/
or /usr/share/mumble-server/
on Unix systems.
Generating stubs
Before being able to use Python to access a Mumble server, you need to generate the relevant Python stubs from the slice file. In order to do so, you
can use the slice2py
executable that should have been as part of the zeroc-ice
Python package. To do so, execute
slice2py <path_to_slice_file>
where <path_to_slice_file>
is the path to the slice file. So if you have the slice file in the current directory, the call would be
slice2py MumbleServer.ice
This will generate a MumbleServer
directory and a MumbleServer_ice.py
in the current directory.
First steps
Once everything has been set up and all stubs have been generated, you can start with the actual Python scripting. The only thing to take care of is
that the generated stubs have to be in your PYTHONPATH
in order to be able to import the MumbleServer
module. The easiest way to accomplish this
is to have the stubs generated in the same directory in which your script lives.
The following script illustrates the essentials of establishing a connection to your server and how to use the Ice interface:
import sys
import Ice
import MumbleServer
def main():
with Ice.initialize(sys.argv) as communicator:
# Establish the connection to the server - make sure the used IP and port match the ones
# in your server's configuration
# "Meta" identifies the object adapter to use and the remaining string after the colon
# specifies the endpoint to connect to. In this case, a TCP endpoint where
# -h specifies the host (IP)
# -p specifies the port
# -t specifies the timeout of the connection in milliseconds
base = communicator.stringToProxy("Meta:tcp -h 127.0.0.1 -p 6502 -t 60000")
# Cast the proxy to a Meta object
meta = MumbleServer.MetaPrx.checkedCast(base)
assert meta is not None
# Iterate over all existing virtual servers
for server in meta.getAllServers():
# Print status of current server making use of the id() and isRunning() methods
print(
f"Found server with ID {server.id()} ({'online' if server.isRunning() else 'offline'})"
)
if server.isRunning():
# For running servers, print how long they have been running already
uptime = server.getUptime()
print(f" -> Has been online for {uptime} seconds")
if __name__ == "__main__":
main()
Note that the first object you have access to after connecting to the server is a Meta
object, which can be seen as the entity managing all
configured virtual servers. It can be used to start/stop existing servers and to create new ones (or delete existing ones).
In most cases you’ll want to use the Meta
object to get a handle of the actual Server
object corresponding to the virtual server you are
interested in. This can then be used to manipulate this specific server (e.g. set configuration options or querying connected users).
Interface documentation
The documentation of what kind of functions can be called (and with what parameters) on Meta
or Server
objects can be found in the slice file
itself. Search for interface Meta
and interface Server
respectively.
Using passwords
If the server has been configured to require a password for read and/or write requests via Ice (cmp. https://www.mumble.info/documentation/mumble-server/scripting/ice/server-setup/), you have to
pass the correct password in form of a context object containing the password. The context object is a dictionary and the password is provided as the
value for the secret
key of said dictionary. All Ice functions related to the Mumble server take the context as an optional last argument when being
called.
As an example consider the following script which sets the SuperUser password on a server that has been configured with icesecret="mypw"
:
import sys
import Ice
import MumbleServer
def main():
with Ice.initialize(sys.argv) as communicator:
base = communicator.stringToProxy("Meta:tcp -h 127.0.0.1 -p 6502 -t 60000")
meta = MumbleServer.MetaPrx.checkedCast(base)
assert meta is not None
context = {"secret": "mypw"}
# We just assume the server we want to modify has ID 1
server = meta.getServer(1, context)
assert server is not None
# Not providing the context with the correct password would make this
# request fail with an InvalidSecretException
server.setSuperuserPassword("Strong password", context)
if __name__ == "__main__":
main()
Troubleshooting
InvalidSecretException
Your request has been blocked because a password is required to perform the given request and you didn’t provide one or the one you provided is incorrect. Alternatively, it could be that the server has completely disabled any requests of this kind (read or write requests).