Getting started with Spirent REST API automation in Python

Spirent is an incredible tool to test the boundaries of network environments. With tons of traffic types, you can simulate nearly whatever you imagine. What’s even better, it can be automated!

Unfortunately, the beginning of this road isn’t that easy. I’ve spent a couple of hours trying to understand how to approach this problem and another few on writing the first automation script before the first major success. So if you’re approaching this issue, and don’t like headaches, grab a cup of coffee, and let’s go with the pure essence!


Let’s take a look at the diagram.

If we want to automate Spirent actions, we need a Spirent VM or physical box. You’re reading this article, so I’m assuming that you already have one. It needs to be connected to the management network, and configured. The remaining interfaces will be used for traffic testing, so they need to be connected to the data network.

The next component we will need is a Spirent Test Center application. We will use it for many different things, but mainly for automation. You can install it on a dedicated VM or even on your local computer. The main requirement is, it needs to have IP connectivity to the Spirent box.

Keep in mind, that Spirent Test Center and your physical/virtual Spirent machine may not work with each other in case of a software version mismatch.

Web daemon setup

The web server is preinstalled with the Spirent Test Center. Before interacting with it, first, we need to run it. You can find it in the main Spirent Test Center directory, because daemon files are located there. We’re interested in both stcweb and stcweb.yaml.

Right after installation, the server is preconfigured, so there is no need to make any changes to the stcweb.yaml file, unless you want to change the default config.

Starting server daemon varies between the systems. On Windows, you just have to execute the stcweb.exe file. On Linux, if you already have exec rights, you can run in by typing ./stcweb command (while your current working directory is the main Spirent Test Center catalog).

In real life, we often want daemons to start automatically after a system reboot. Keep in mind, that the solutions described above are ephemeral, which means that daemons won’t start after reloading the system.

Now, with a working web daemon, we’re ready to use Python!

Python library

There is a Python library for the REST operations on Spirent Test Center. You can get more details here.

To install it, use pip module – pip install -U stcrestclient

After installation, we’re ready to go, but before jumping straight to the code, I would like to show you an interesting utility of the stcrestclient library. It’s TCSSH – an interactive shell to test REST API queries.

If you’re eagerly waiting for Python code examples, just skip the following section.


To open an interactive shell, we need to execute tccsh command for Linux. In the following examples, I’ve used Windows, and to enter interactive mode, I had to execute the tccsh.exe.

Right after entering the command, we’re prompted for the IP address of the Spirent Test Center web server, and here’s a first catchy thing. TCCSH by default tries to connect to the server on port 80, but by default STC web server is running on port 8888, so the connection won’t be successful.

(NetworkAutomation) PS C:\Users\Garzum\Documents\Projects\SpirentAPI> tccsh.exe
Cannot connect to STC server:

To adjust the port, we need to use the -p switch followed by the port number, so 8888.

(NetworkAutomation) PS C:\Users\Garzum\Documents\Projects\SpirentAPI> tccsh.exe -p 8888
Enter server:
Welcome to Spirent TestCenter Command Shell (tccsh)

Now, we’re ready to explore!

By typing ? you can get a list of available commands.> ? Documented commands (type help <topic>): ======================================== chassis       exit           recording_on    stc_disconnectall chassis_info  files          server          stc_get connections   help           set_timeout     stc_help debug_off     info           stc_apply       stc_log debug_on      is_connected   stc_config      stc_perform delete        join           stc_connect     system_info delete_all    kill           stc_connectall  upload download      ls             stc_create      wait_until_complete download_all  new            stc_delete end           recording_off  stc_disconnect

Now, to proceed, we need to create a session. We can display a list of already existing by typing ls.> ls>

Right now the session list is empty. Let’s create one with new command. It takes one argument – the session name.> new TestSession
Creating new session "TestSession" for user "Garzum" ...
Created and joined session: TestSession - Garzum - Garzum> ls
[TestSession - Garzum] <-- current session

After creating a session, the shell automatically joined it. Now, the session list is not empty anymore.

What’s worth mentioning here is the session entry in the ls command output. Every session is determined by its name and user. In my case, I’ve created a session named TestSession, and my username is Garzum. The final identifier is TestSession – Garzum. You can use it to join the session next time you open TCSSH.> join TestSession - Garzum
Joined session "TestSession - Garzum" (BLL ver: 5.42.2346.0000)

After joining the session, we can fully utilize TCSSH commands. Let’s grab information about the basic built-in object, that’s present in every session – system1. - Garzum> stc_get system1
Active: true
Name: StcSystem 1
Version: 5.42.2346.0000
children: activeeventmanager1 commandstatusupdate1 userlogresult1 automationoptions temevaconfig1 userinfo1 physicalchassismanager1 licenseservermanager1 temevaresultsconfig1 sequencer1 sequencergroupcommand1 stmmethodologymanager1 ifmanager1 linkregistry1 featuresupportedversion1 project1 resultproviderregistry1 spirent.results.resultdimensionproviderregistry1 clientinfo1
{'Active': 'true', 'Name': 'StcSystem 1', 'OtfLicensingWarningMessageJson': '', 'Version': '5.42.2346.0000', 'children': 'activeeventmanager1 commandstatusupdate1 userlogresult1 automationoptions temevaconfig1 userinfo1 physicalchassismanager1 licenseservermanager1 temevaresultsconfig1 sequencer1 sequencergroupcommand1 stmmethodologymanager1 ifmanager1 linkregistry1 featuresupportedversion1 project1 resultproviderregistry1 spirent.results.resultdimensionproviderregistry1 clientinfo1'}

Now, we have a complete object structure.

Right now you may be wondering why should you care about TCSSH and its capabilities, but if you take a look at further Python examples, you will find many similarities. It’s also worth to know TCSSH to be able to experiment with API calls. Later, after creating more custom objects, you can use the stc_get command to retrieve their structure without the need to execute any Python code.

But enough on the TCSSH, let’s jump to Python!

Python code

Let’s start with similar operations, but using Python.

from stcrestclient import stchttp

# Connection variables
stc_server = ''
port = 8888

# Session variables
user_name = "Garzum"
session_name = "Script"
session_id = f"{session_name} - {user_name}"

stc_session = stchttp.StcHttp(stc_server, port=port)

system_info = stc_session.system_info()
print(f"System info: {system_info}")

sessions = stc_session.sessions()
print(f"List of sessions before createting a new one: {sessions}")

Here, we have a code snipped with variables, that will be used for connection and session.

To establish an STC(Spirent Test Center) connection, we have to create a stchttp.StcHttp object with connection details – STC server IP address, and port.

After that, we’re able to interact with the Spirent Test Center API, similarly to the TCSSH examples. In the code above, I’ve received system information and existing sessions.

System info: {'stcapi_version': '3.0.13', 'min_api_version': 1, 'max_api_version': 1, 'system_time': '2023-09-18T17:03:46+02:00'}
List of sessions before createting a new one: []

The sessions list is empty, so let’s create one.

    print(f"Creating new session: {session_id}")
    stc_session.new_session(user_name=user_name, session_name=session_name)
    print("Created a new session")
except RuntimeError:
    print("Session already exists, joining to it")
    print(f"Joined session: {session_id}")

sessions = stc_session.sessions()
print(f"List of sessions after creating/joining: {sessions}")

While creating a new session the RuntimeError can occur. This means that creation was unsuccessful. In most cases, it’s because such a session already exists:

RuntimeError: failed to create session: 409 Conflict: session already exists: Script - Garzum

That’s why we have to handle such scenarios. If we detect, that such session already exists by handling exception, we can join it.

There is however another way to handle this. If we add a kill_existing = True argument to the new_session method, the STC client will automatically kill the existing session, and create a new one without raising an exception.

After creating our session, we’re retrieving the session list once again to see, if it’s there.

List of sessions after creating/joining: ['Script - Garzum']

We can’t do much with Spirent Test Center without creating a project. That’s the next step in the code.

stc_project = stc_session.create("project")
print(f"Created a new project: {stc_project}")

This is a good point to start writing configuration code for our traffic tests, however, it’s out of the scope of this article. That’s why we will terminate our session.

print("Ending session")

You can view the complete code in the GitLab repository.

If you’re curious how to setup a basic traffic flow with Spirent, make sure to check out my article on this.


Automating Spirent may seem scary at first, but after taking one step after another you end up having a fully prepared environment. The presented method can serve as a solid foundation for further automation. In the following articles, we will take a look at how we can use it for traffic tests.

See you!


One thought on “Getting started with Spirent REST API automation in Python

Leave a Reply

Your email address will not be published. Required fields are marked *