The MIMIC Python API is an optional Update Wizard package, and requires the use of the Python 2.7 or later. Python is already installed on Linux platforms, but will have to be installed on the other platforms. MIMIC has been tested with Python 2.7.3 and upto 3.8 on Linux, and Python 2.7 and 3.5.1 on Windows.
This section maps each Tcl mimicsh command to the equivalent call in the native Python API — the object model (modelled after the Java API). You create a Client, open a Session, get an Agent from the session and a Valuespace from the agent, then call methods on those objects:
session = client.open_session(host, port) # a Session
agent = session.get_agent(1) # an Agent
vspace = agent.get_valuespace() # a Valuespace
Unlike the Tcl shell there is no "assigned/current" session or agent — you hold
each object in a variable and call methods on it. (The dotted
mimic.agent.... syntax comes from a separate Tcl-compatibility shim,
which can be disabled; the tables below give the native calls.)
Sessions are managed by a Client; open_session returns the Session object you keep and use.
| Tcl | Python (native) |
|---|---|
| mimic session open host port | session = client.open_session(host, port) |
| mimic session close session | client.close_session(session) |
| mimic session list | client.list_sessions() |
| mimic session properties | session.get_host(), session.get_port(), session.get_user() |
| mimic session assign session | no native equivalent (Tcl shim only) |
| mimic session assigned | no native equivalent (Tcl shim only) |
| Tcl | Python (native) |
|---|---|
| mimic get cfgfile | session.get_cfgfile() |
| mimic get max | session.get_max() |
| mimic get last | session.get_last() |
| mimic get version | session.get_version() |
| mimic get clients | session.get_clients() |
| mimic get configured_list | session.get_configured_list() |
| mimic get configured_ranges | session.get_configured_ranges() |
| mimic get active_list | session.get_active_list() |
| mimic get active_ranges | session.get_active_ranges() |
| mimic get active_data_list | session.get_active_data_list() |
| mimic get changed_config_list | session.get_changed_config_list() |
| mimic get changed_state_list | session.get_changed_state_list() |
| mimic get log | session.get_log() |
| mimic get interfaces | session.get_interfaces() |
| mimic get cfgfile_changed | session.get_cfg_file_changed() |
| mimic get privdir | session.get_sim_privdir() |
| mimic get protocols | session.get_protocols() |
| mimic get product | session.get_product() |
| mimic get netaddr | session.get_netaddr() |
| mimic get netdev | session.get_netdev() |
| mimic get licensing | session.get_licensing() |
| mimic get threads | session.get_threads() |
| Tcl | Python (native) |
|---|---|
| mimic set log logfile | session.set_log(logfile) |
| mimic load "agent.cfg" | session.cfg_load("agent.cfg") |
| mimic diag N | session.diag(N) |
| Tcl | Python (native) |
|---|---|
| mimic cfg new [agents] | session.cfg_new(agents="") |
| mimic cfg load file [agents [start [merge]]] | session.cfg_load(file, agents="", start="", merge="") |
| mimic cfg save [agents] | session.cfg_save(agents="") |
| mimic cfg saveas file [agents] | session.cfg_saveas(file, agents="") |
Get the Agent with session.get_agent(N) and call methods on it; there is no assign/assigned. The multi-agent mget/mset are Session methods (they take an agent list).
| Tcl | Python (native) |
|---|---|
| mimic agent assign N | agent = session.get_agent(N) (no "assign" — hold the Agent) |
| mimic agent assigned | no native equivalent; agent.get_agent_no() gives the number |
| mimic agent start | agent.start() |
| mimic agent stop | agent.stop() |
| mimic agent pause [time] | agent.pause_now() / agent.pause_at(time) |
| mimic agent halt | agent.halt() |
| mimic agent resume | agent.resume() |
| mimic agent add addr mibs | agent.configure(addr, mibs) |
| mimic agent remove | agent.remove() |
| mimic agent get param | agent.get_<param>() (see param map below) |
| mimic agent set param value | agent.set_<param>(value) (see param map below) |
| mimic agent mget param {N1 N2 N3} | session.agent_mget(param, [N1,N2,N3]) |
| mimic agent mset param N1 V1 N2 V2 ... | session.agent_mset(param, [N1,N2], [V1,V2]) |
Agent get / set param name mapping (Tcl name to native Agent method):
| Tcl param | get method | set method |
|---|---|---|
| "interface" | get_interface() | set_interface(val) |
| "host" | get_host() | set_host(val) |
| "mask" | get_mask() | set_mask(val) |
| "port" | get_port() | set_port(val) |
| "read" | get_read_community() | set_read_community(val) |
| "write" | get_write_community() | set_write_community(val) |
| "mibs" | get_mibs() | set_mibs(val) |
| "sim" | get_sim() | (read-only) |
| "scen" | get_scen() | (read-only) |
| "pdusize" | get_pdusize() | set_pdusize(val) |
| "protocol" | get_protocols() | set_protocols(val) |
| "delay" | get_delay() | set_delay(val) |
| "start" | get_starttime() | set_starttime(val) |
| "state" | get_state() | (read-only) |
| "statistics" | get_statistics() | (read-only) |
| "drops" | get_drops() | set_drops(val) |
| "changed" | get_changed() | (read-only) |
| "config_changed" | get_config_changed() | (read-only) |
| "state_changed" | get_state_changed() | (read-only) |
| "trace" | get_trace() | set_trace(val) |
| "validate" | get_validate() | set_validate(val) |
| "owner" | get_owner() | (read-only) |
| "privdir" | get_privdir() | (read-only) |
| "oiddir" | get_oiddir() | set_oiddir(val) |
| "inform_timeout" | get_inform_timeout() | set_inform_timeout(val) |
| "inform_retries" | get_inform_retries() | set_inform_retries(val) |
| "num_starts" | get_num_starts() | (read-only) |
| Tcl | Python (native) |
|---|---|
| mimic agent ipalias list | agent.list_ipaliases() |
| mimic agent ipalias add "addr,port" [mask [iface]] | agent.add_ipalias(address, port=161, mask="", interface="") |
| mimic agent ipalias delete "addr,port" | agent.del_ipalias(address, port=161) |
| mimic agent ipalias start "addr,port" | agent.start_ipalias(address, port=161) |
| mimic agent ipalias stop "addr,port" | agent.stop_ipalias(address, port=161) |
Note: natively the address and port are separate arguments (not the combined "addr,port" string the Tcl form uses) — e.g. agent.add_ipalias("192.9.216.1", 161).
| Tcl | Python (native) |
|---|---|
| mimic agent store list | agent.agent_store_list() |
| mimic agent store exists var | agent.agent_store_exists(var) |
| mimic agent store persists var | agent.agent_store_persists(var) |
| mimic agent store get var | agent.agent_store_get(var) |
| mimic agent store set var val persist | agent.agent_store_set(var, val, persist) |
| mimic agent store append var val persist | agent.agent_store_append(var, val, persist) |
| mimic agent store unset var | agent.agent_store_unset(var) |
| mimic agent store copy other_agent_no | agent.agent_store_copy(other) |
| Tcl | Python (native) |
|---|---|
| mimic agent trap list | agent.trap_list() |
| mimic agent trap config list | agent.trap_config_list() |
| mimic agent trap config add dest port | agent.trap_config_add(dest, port) |
| mimic agent trap config delete dest port | agent.trap_config_del(dest, port) |
Note: agent.trap_config_delete(dest, port) is an accepted alias of trap_config_del() — both spellings work.
Value commands operate on a Valuespace obtained from the agent: vspace = agent.get_valuespace().
| Tcl | Python (native) |
|---|---|
| mimic value pos | vspace.get_pos() |
| mimic value pos ifEntry | vspace.set_pos("ifEntry") |
| mimic value list | vspace.get_objects() |
| mimic value add ifEntry 510 | vspace.add("ifEntry", 510) |
| mimic value remove ifEntry 510 | vspace.remove("ifEntry", 510) |
| mimic value instances ifDescr | vspace.get_instances("ifDescr") |
| mimic value variables ifInOctets 1 | vspace.get_variables("ifInOctets", 1) |
| mimic value get sysDescr 0 v | vspace.get_value("sysDescr", 0, "v") |
| mimic value set sysContact 0 v Sucharu | vspace.set_value("sysContact", "0", "v", "Sucharu") |
| mimic value mget obj inst var obj inst var ... | vspace.mget_value(objects, instances, variables) |
| mimic value mset obj inst var val obj inst var val ... | vspace.mset_value(objects, instances, variables, values) |
| mimic value unset obj inst var | vspace.unset_value(obj, inst, var) |
| mimic value munset obj inst var obj inst var ... | vspace.munset_value(objects, instances, variables) |
| mimic value eval obj inst | vspace.eval_value(obj, inst) |
| mimic value meval obj inst obj inst ... | vspace.meval_value(objects, instances) |
| mimic value oid name | vspace.get_oid(object) |
| mimic value name oid | vspace.get_name(Oid(oid)) |
| mimic value split oid | vspace.split_oid(Oid(oid)) |
| mimic value mib objname | vspace.get_mib(objname) |
| mimic value info objname | vspace.get_info(objname) |
| mimic value minfo obj1 obj2 ... | vspace.get_minfo([obj1, obj2, ...]) |
| mimic value state get objname | vspace.get_state(objname) |
| mimic value state set objname val | vspace.set_state(objname, val) |
Notes: the multi- calls (mget/mset/munset/meval) take parallel lists — (objects, instances, variables[, values]) — not flat interleaved args; OID arguments/returns use the Oid class.
| Tcl | Python (native) |
|---|---|
| mimic store list | session.store_list() |
| mimic store exists var | session.store_exists(var) |
| mimic store persists var | session.store_persists(var) |
| mimic store get var | session.store_get(var) |
| mimic store set var val persist | session.store_set(var, val, persist) |
| mimic store append var val persist | session.store_append(var, val, persist) |
| mimic store unset var | session.store_unset(var) |
| mimic store mget {var1 var2} | session.store_mget([var1, var2]) |
| mimic store lreplace var index val | session.store_lreplace(var, index, val) |
| mimic store mlreplace var1 idx1 val1 var2 idx2 val2 ... | session.store_mlreplace([vars], [idxs], [vals]) |
| Tcl | Python (native) |
|---|---|
| mimic trap config list | session.trap_config_list() |
| mimic trap config add dest port | session.trap_config_add(dest, port) |
| mimic trap config delete dest port | session.trap_config_delete(dest, port) |
Note: session.trap_config_del(dest, port) is an accepted alias of trap_config_delete() — both spellings work.
| Tcl | Python (native) |
|---|---|
| mimic access get adminuser | session.get_access_adminuser() |
| mimic access get admindir | session.get_access_admindir() |
| mimic access get acldb | session.get_access_acldb() |
| mimic access get enabled | session.get_access_enabled() |
| mimic access set enabled val | session.set_access_enabled(val) |
| mimic access set adminuser user | session.set_access_adminuser(user) |
| mimic access set admindir dir | session.set_access_admindir(dir) |
| mimic access set acldb db | session.set_access_acldb(db) |
| mimic access list | session.list_access() |
| mimic access add user agents mask | session.add_access(user, agents, mask) |
| mimic access del user | session.del_access(user) |
| mimic access save file | session.save_access(file) |
| mimic access load file | session.load_access(file) |
Each protocol module accepts its own set of protocol msg sub-commands, but they all map to Python by one uniform rule:
The table below gives one representative command per module; it is not exhaustive. For the complete command set of a module, follow its reference link.
| Module | Representative (Tcl) | Python (native) | Full command list |
|---|---|---|---|
| snmpv3 | mimic protocol msg snmpv3 get args | session.protocol_msg("snmpv3", "get args") | reference |
| TELNET | mimic protocol msg TELNET get args | session.protocol_msg("TELNET", "get args") | reference |
| SSH | mimic protocol msg SSH get args | session.protocol_msg("SSH", "get args") | reference |
| NETFLOW | mimic protocol msg NETFLOW get args | session.protocol_msg("NETFLOW", "get args") | reference |
| SFLOW | mimic protocol msg SFLOW get args | session.protocol_msg("SFLOW", "get args") | reference |
| WEB | mimic protocol msg WEB get args | session.protocol_msg("WEB", "get args") | reference |
| MQTT | mimic protocol msg MQTT get args | session.protocol_msg("MQTT", "get args") | reference |
| IPMI | mimic protocol msg IPMI get args | session.protocol_msg("IPMI", "get args") | reference |
| DHCP | mimic protocol msg DHCP get args | session.protocol_msg("DHCP", "get args") | reference |
| TFTP | mimic protocol msg TFTP get args | session.protocol_msg("TFTP", "get args") | reference |
The Hello, World! program for the Python MIMIC API is these commands typed into the mimicsh.py shell:
% ./mimicsh.py
MIMIC Python API shell
Copyright (c) 2012-2013 Gambit Communications, Inc.
Type "help;" for online help.
mimicsh-python>>> session.cfg_new()
mimicsh-python>>> session.cfg_load('agent.cfg')
mimicsh-python>>> agent = session.get_agent(1)
mimicsh-python>>> agent.start()
mimicsh-python>>>
While you are doing this, notice how your MIMICview reacts to each command - it synchronizes with the simulator to keep up with the latest state. When the first agent turns green, it has synchronized to your state. You have seen that you can control MIMIC from any number of clients using the MIMIC API.
You can also do this non-interactively by saving these 4 commands into a file, and running mimicsh.py with the --script option:
% cat > hello.py
session.cfg_new()
session.cfg_load('agent.cfg')
agent = session.get_agent(1)
agent.start()
^D
% ./mimicsh.py --script hello.py
These example programs with source code show different usage of the Python API to control MIMIC:
The TestApp.py program is an small test program to exercise the MIMIC API.
The tkdemo.py sample program uses the TkInter GUI framework to implement the equivalent of the tkdemo.mtcl Tcl script.
The mimicdthreads.py client displays MIMICD thread statistics to determine performance of MIMICD threads. You can download it with Update Wizard.
Another optional Update Wizard patch is this MIMICview clone implemented in Python.
The Python API has been tested against Jython using version 2.2.1 on both Windows Vista and Linux (Fedora Core 8).
A performance test of the Python API in a Jython environment shows a significant loss in response time as compared to a native Python enviroment.