Top Tips for using the PaperCut MF/NG public web services API
The MF/NG public API is super handy for a lot of different PaperCut server administration tasks, from the simple to the complex. This post provides some hints and tips to help you get the most from the API.
Before going any further you should read the API Overview . This post mainly expands on the overview material and calls out specific topics that we have been asked about before.
What can you do with the API?
The functionality exposed in the public web services API is broad and covers things such as:
- managing user accounts, shared accounts, groups and printers. It includes things such as updating users’ account balances, managing security settings on shared accounts and so on
- adding job details from a third party system
- managing admin users
- setting and setting advanced config settings
- starting import jobs.
Starting out with the server-command utility
The easiest way to use the API is to use the server-command
program from a script. This example uses the Bash shell as the script engine. If you are using Windows you will either need to install the Windows 10 Linux subsystem, Cygwin, or convert the script to a Windows batch file (more on how to support Windows in the resources
links
below).
Let’s start with the following example. This script will swap the primary and secondary card numbers for every user in the PaperCut database.
server-command list-user-accounts | while read x;do
primary=$(server-command get-user-property $x "secondary-card-number")
secondary=$(server-command get-user-property $x "primary-card-number")
server-command set-user-property $x "primary-card-number" "$primary"
server-command set-user-property $x "secondary-card-number" "$secondary"
done
There are a number of points to note:
- The
server-command
utility can only be run on the PaperCut application server - The path to the program is
[app-dir]/server/bin/<platform>/server-command
and you will need to select the correct path for your server platform server-command
will perform one command (API call) at a time. If you are performing very large bulk updates you might find this slow.- The program does not return error codes in an expected fashion because of complex types of errors that can occur. You will need to parse the text output.
The example above, and others, can be found on the
PaperCut Examples
repository. Additional examples can also be found on the PaperCut MF/NG server [app dir]/server/examples/scripting
.
So let’s look at the example script above in more detail. I suggest that you open up a command shell (cmd.exe on Windows) and try these out for yourself. Just make sure that server-command
is on your path.
So the first call is to get a list of the users (internal and external) in PaperCut. When I run this command on my test system I get this:
$ server-command list-user-accounts
ah
alec
copieruser
jane
john
suhail
The next few commands get repeated for each user (that’s the magic while read...
bit).
When we have each user name we can a) read both card numbers from the database with get-user-property
and then b) write them back to the database with set-user-property
command.
So for example:
In Windows PowerShell
&"c:\Program Files\PaperCut MF\server\bin\win\server-command.exe" set-user-property alec primary-card-number 89879789
On Linux
~papercut/server/bin/linux-x64/server-command set-user-property alec primary-card-number 89879789
More information about server-command
here
.
Using the API
If you want to use the API across the network or incorporate API calls into something larger you need to use the API directly. You should also consider using the API because it can be three to ten times faster than using server-command
.The following discussion assumes you have read the
overview
and refers you to other documentation as we progress.
The following code examples are in Python 3. This is a common language and should provide some simple code fragments that you can translate into your preferred programming language.
We also provide examples in C#, Ruby, PHP and Java (on your PaperCut server go to [app dir]/server/examples/webservices/
). On our GitHub repo you can also find a Perl
example
contributed by
@Joffcom
(more contributions always welcome).
XML-RPC
All the method calls use XML-RPC as the transport mechanism. You can find more details about XML-RPC here .
If you are new to XML-RPC programming you might find this blog post useful.
However generally you don’t need to worry about the protocol details as these are handled by a library. Python 3 provides the xmlrpc library. Please look in the blog post linked above for suggestions of libraries you can use in other common programing languages. Otherwise the Google search engine is your friend.
Security
Pay special attention to the section on security in the overview.
The authentication token (required on each method call) should be defined in the advanced config key auth.webservices.auth-token
. This is because:
- Using the admin password could be a security risk if the password leaks
- It’s possible to define a very large random secret in the
auth.webservices.auth-token
config key which would be secure, but not suitable as an admin password. - Using the admin password is also approximately 10 times slower because the auth token must be processed on each call.
In addition the IP white list can be configured in the Admin GUI or by setting the auth.webservices.allowed-addresses
advanced config key, which you can do via the server-command
utility (or API using the admin password as you auth key).
Another security consideration is the use of end-to-end encryption via the use of a Transport Layer Security(TLS). This allows for the data to be securely passed from client to server - meaning you can pass your auth.webservices.auth-token
to the PaperCut server without having it exposed on the network.
An example of how to do this in Python:
from ssl import create_default_context, Purpose
# Prefer HTTPS connection
host="https://localhost:9192/rpc/api/xmlrpc"
# If not localhost then this address will need to be whitelisted in PaperCut auth="token"
# Value defined in advanced config property "auth.webservices.auth-token". Should be random
proxy = xmlrpc.client.ServerProxy(host, verbose=False, context = create_default_context(Purpose.CLIENT_AUTH))
You can now make API calls through the proxy instance.
Making API calls
Before making API calls it’s usual to set up values. In addition most XML-RPC libraries require you to set up some library object for later calls. In Python this looks like:
#!/usr/bin/env python3
import xmlrpc.client
# If not localhost then this address will need to be whitelisted in PaperCut
host="http://localhost:9191/rpc/api/xmlrpc"
# Value defined in advanced config property "auth.webservices.auth-token". Should be random
auth="token"
proxy = xmlrpc.client.ServerProxy(host)
You can now make method calls. For example:
user="aUser"
if not proxy.api.isUserExists(auth, user): print("Can't find user {}".format(user)
Notice the parameter auth
, which must be provided in every API call.
The API overview does not provide enough detail on each API (specific parameters and types) and developers will need to refer to the detailed documentation installed on the PaperCut MF/NG server at [app dir]/server/examples/webservices/java/docs/api/index.html
. Note that this Javadoc does not provide any information about the requirement to add the auth
token as the first method parameter to every call.
Troubleshooting
- You get the error
ERROR: java.lang.NoSuchMethodException:
usually you have either:- Forgotten to add the auth token parameter,
- Misspelled the method name,
- Provided the wrong number of parameters or
- At least one parameter is the wrong type. For instance supplying an integer when a double float type is required.
- You are getting an error message about the client IP address not being whitelisted, even though you added it in PaperCut.
Often your network or IT infrastructure is mangling the IP address in some fashion. Look in the PaperCut server log to see the IP address that PaperCut is seeing — look for the string BaseXMLRPCServlet
- You have checked everything in your code and it’s still not working.
- Check the PaperCut server log — look for the string
BaseXMLRPCServlet
- Double check your XML content, including the case of XML element names. For instance it’s
<methodName>
, not<methodname>
- Do some low level XML-RPC debugging
- Install Curl (on macOS and Linux it’s already installed)
- Optionally set up an access token (advanced config key auth.webservices.auth-token)
- Create an XML data file with your API call parameters within the content of your method call. For instance:
- Check the PaperCut server log — look for the string
<?xml version="1.0"?>
<methodCall>
<methodName>api.getUserAccountBalance</methodName>
<params>
<param>
<value>token</value>
</param>
<param>
<value>username</value>
</param>
</params>
</methodCall>
- Run a command similar to:
curl -v -H "content-type:text/xml" http://<servername>:9191/rpc/api/xmlrpc --data @file.xml
and check the output.
In shells that support here documents you can combine this into a single command or file, for example in PowerShell
@'
<?xml version="1.0"?>
<methodCall>
<methodName>api.getUserAccountBalance</methodName>
<params>
<param>
<value>token</value>
</param>
<param>
<value>username</value>
</param>
</params>
</methodCall>
'@ | curl -v -H "content-type:text/xml" http://localhost:9191/rpc/api/xmlrpc --data `@-
Some partners have reported success in using Postman as a debugging tool as well.
Proxy Wrappers
The Python example above uses an XML-RPC library and the application programmer makes direct calls on the network API to connect to the PaperCut server. For certain languages (Java and C#) we have created example proxy wrappers around the network code.
In this case PaperCut have provided classes that implement each API call. The developer just makes a method call and the proxy class handles the marshalling and unmarshaling of the network calls.
Please note that the example proxy classes are often not up to date with the latest API changes.
You can find the proxy wrapper examples on the PaperCut MF/NG server:
- Java:
[app dir]/server/examples/webservices/java/ServerCommandProxy.java
- C#:
[app dir]/server/examples/webservices/csharp/ServerCommandProxy.cs
More Resources
- Email Group — https://groups.google.com/forum/#!forum/papercut-webservices-api
- More information about PaperCut APIs in general — https://www.papercut.com/kb/Category/ScriptingandAPIs
- Online chat forum — https://gitter.im/PaperCutSoftware/PaperCutExamples
- Integrating the C# proxy wrapper into Windows PowerShell — https://www.papercut.com/kb/Main/AdministeringPaperCutWithPowerShell
- Managing PaperCut MF/NG Shared Accounts and User Settings via IDM Integration
- Advanced Technical Notes on using
getTaskStatus()
— https://github.com/PaperCutSoftware/PaperCutExamples/wiki/Public-Web-Services-API
Comments