The current version of the Python zendir module uses asynchronous web calls when accessing the API. This enables multiple requests to the same simulation to be made concurrently. In order to make these calls using Python, an asynchronous library such as asyncio must be used to run functions in another call stack.


Asynchronous Runner

In the case of the examples, it is recommended where possible to use the Zendir runner module to run single simulations, as it will ensure the simulations are created and cleaned up correctly. All of the example files use the simulation runner in some way, so make sure to refer to the source code provided by the Example Scenarios repository. To use the runner, an asynchronous main function must be created in the Python script.

from zendir import runner, Simulation, Client
import credential_helper
 
async def main(simulation: Simulation) -> None:
    # ...
    # Code associated with the simulation goes here
    # ...
 
client: Client = credential_helper.fetch_client()
runner.run_simulation(client, main, dispose=True)

NOTE

The dispose=True parameter will destroy the simulation once the code in the main function has completed execution. This will ensure that any old simulations are cleaned up correctly. However, if attempting to load data from the same simulation by multiple scripts, this should be disabled.


Multiple Simulations

The runner module also has a way of executing multiple similar simulations at the same time. This is useful for Monte-Carlo styled simulations, where one configuration for each simulation can be created, with just some variables changed between the simulations. This can be done using the run_simulations function.

async def main(simulation: Simulation, index: int) -> None:
    # ...
    # Code associated with the simulation with 'index' goes here
    # ...
 
# In this case, create 5 identical simulations based on the code in `main`
client: Client = credential_helper.fetch_client()
runner.run_simulations(client, 5, main, dispose=True)

Based on the index parameter passed through the main function, different configurations could be amended to the simulation configuration. The index starts from 0 and goes until the value of n - 1, where n is the number of simulations created by the run_simulations method.


Manual Simulation Creation

Alternatively, instead of using the runner module, asyncio could be used instead, which can be more flexible with creating asynchronous requests and tasks. However, it requires the user to manage their simulations and create them correctly. Using the asyncio Python module, which can be installed by pip, the following snippet could be used to create a simulation.

import asyncio
from zendir import Simulation, Client
 
async def main():
	# Create the client and a new simulation, using the 'await' for coroutines
    client = Client(token="API TOKEN")
    simulation: Simulation = await Simulation.create(client)
    
    # ...
    # Code associated with the simulation goes here
    # ...
 
asyncio.run(main())