All Driver Arguments¶
The basic usage section outlined the most commonly used driver arguments, please see the following pages to see all supported driver arguments:
Most of these attributes actually get passed from the
Driver (or sub-class such as
NXOSDriver) into the
Channel classes, so if you need to modify any of these values after instantiation you should do so
on the appropriate object -- i.e.
Due to the nature of Telnet/SSH there is no good way to know when a command has completed execution. Put another way , when sending any command, data is returned over a socket, that socket doesn't ever tell us when it is "done " sending the output from the command that was executed. In order to know when the session is "back at the base prompt/starting point" scrapli uses a regular expression pattern to find that base prompt.
This pattern is contained in the
comms_prompt_pattern setting or is created by joining all possible prompt patterns
in the privilege levels for a "core" device type. In general, you should not change the patterns unless you have a
good reason to do so!
Driver (default, but changeable) pattern is:
comms_prompt_pattern "should" use the start and end of line anchors as all regex searches in scrapli are
multi-line (this is an important piece to making this all work!). While you don't need to use the line anchors its
probably a really good idea! Also note that most devices seem to leave at least one white space after the final
character of the prompt, so make sure to account for this! Last important note -- the core drivers all have reliable
patterns set for you, so you hopefully don't need to bother with this too much!
The above pattern works on all "core" platforms listed above for at the very least basic usage. Custom prompts or host names could in theory break this, so be careful!
If you use a platform driver, the base prompt is set in the driver, so you don't really need to worry about this!
comms_prompt_pattern pattern can be changed at any time at or after instantiation of a scrapli object, and is
done so by modifying
conn is your scrapli connection object. Changing
this can break things though, so be careful! If using any
NetworkDriver sub-classes you should modify the
privilege level(s) if necessary, and not the
Lots of times when connecting to a device there are "things" that need to happen immediately after getting connected
. In the context of network devices the most obvious/common example would be disabling paging (i.e. sending
length 0 on a Cisco-type device). While scrapli
Driver (the base driver) and
GenericDriver do not know or care
about disabling paging or any other on connect type activities, scrapli of course provides a mechanism for allowing
users to handle these types of tasks. Even better yet, if you are using any of the core drivers (
IOSXRDriver, etc.), scrapli will automatically have some sane default "on connect" actions (namely disabling
If you were so inclined to create some of your own "on connect" actions, you can simply pass those to the
on_open argument of
Scrape or any of its sub-classes (
IOSXEDriver, etc.). The value of this argument
must be a callable that accepts the reference to the connection object. This allows for the user to send commands or
do really anything that needs to happen prior to "normal" operations. The core network drivers disable paging
functions all call directly into the channel object
send_input method -- this is a good practice to follow as
this will avoid any of the
NetworkDriver overhead such as trying to attain privilege levels -- things like this
may not be "ready" until after your
on_open function is executed.
Below is an example of creating an "on connect" function and passing it to scrapli. Immediately after authentication is handled this function will be called and disable paging (in this example):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Note that this section has talked almost exclusively about disabling paging, but any other "things" that need to happen in the channel can be handled here. If there is a prompt/banner to accept you should be able to handle it here. The goal of this "on connect" function is to allow for lots of flexibility for dealing with whatever needs to happen for devices -- thus decoupling the challenge of addressing all of the possible options from scrapli itself and allowing users to handle things specific for their environment.
Lastly, while the
on_open method should be synchronous or asyncio depending on the driver -- meaning that if using
an async driver, it will await the
on_open callable, so it must be asynchronous!
As you may have guessed,
on_close is very similar to
on_open with the obvious difference that it happens just
prior to disconnecting from the device. Just like
on_close functions should accept a single argument
that is a reference to the object itself. As with most things scrapli, there are sane defaults for the
on_close functions, but you are welcome to override them with your own function if you so chose!
scrapli supports several timeout options:
timeout_socket is exactly what it sounds where possible. For the ssh2 and paramiko transports we create our own
socket and pass this to the created object (paramiko or ssh2 object). The socket is created with the timeout value
set in the
timeout_socket attribute. For telnet and system transports we do not create a socket ourselves so this
value is used slightly differently.
For telnet, the
timeout_socket is used as the timeout for telnet session creation. After the telnet session is
created the timeout is reset to the
timeout_transport value (more on that in a second).
For system transport,
timeout_socket governs the
ConnectTimeout ssh argument -- which seems to be very similar to
socket timeout in paramiko/ssh2.
timeout_transport is intended to govern the timeout for the actual transport mechanism itself. For paramiko and
ssh2, this is set to the respective libraries timeout attributes. For telnet, this is set to the telnetlib timeout
value after the initial telnet session is stood up. For system transport, this value is used as the timeout value
for read and write operations (handled by operation timeout decorator).
timeout_ops sets a timeout value for individual operations -- or put another way, the timeout for each
Driver Privilege Levels¶
The "core" drivers understand the basic privilege levels of their respective device types. As mentioned previously
, the drivers will automatically attain the "privilege_exec" (or equivalent) privilege level prior to executing "show
" commands. If you don't want this "auto-magic" you can use the base driver (
Driver) or the
privileges for each device are outlined in the platforms
driver.py file - each privilege is an object of the base
PrivilegeLevel class which uses slots for the attributes. This used to be a named tuple, however as this was
immutable it was a bit of a pain for users to modify things on the fly.
As an example, the following privilege levels are supported by the
Each privilege level has the following attributes:
- pattern: regex pattern to associate prompt to privilege level with
- name: name of the priv level, i.e. "exec"
- previous_priv: name of the "lower"/"previous" privilege level
- deescalate: command used to deescalate from this privilege level (or an empty string if no lower privilege)
- escalate: command used to escalate to this privilege level (from the lower/previous privilege)
- escalate_auth: True/False there is auth required to escalate to this privilege level
- escalate_prompt: pattern to expect when escalating to this privilege level, i.e. "Password:" or any empty string
If you wish to manually enter a privilege level you can use the
acquire_priv method, passing in the name of the
privilege level you would like to enter. In general, you probably won't need this too often though as the driver
should handle much of this for you.
1 2 3 4 5 6 7 8 9 10
Configure Exclusive and Configure Private (IOSXR/Junos)¶
IOSXR and Junos platforms have different configuration modes, such as "configure exclusive" or "configure private ". These alternate configuration modes are represented as a privilege level just like the "regular" configuration mode. You can acquire an "exclusive" configuration session on IOSXR as follows:
1 2 3 4 5 6 7 8 9 10
Of course you can also pass this privilege level name to the
send_configs_from_file methods as well:
1 2 3 4 5 6 7 8 9 10
Note that the name of the privilege level is "configuration_exclusive" -- don't forget to write the whole thing out!
Configure Session (EOS/NXOS)¶
EOS and NXOS devices support configuration "sessions", these sessions are a little bit of a special case for scrapli
. In order to use a configuration session, the configuration session must first be "registered" with scrapli -- this
is so that scrapli can create a privilege level that is mapped to the given config session/config session name
register_configuration_session method that accepts a string name of the configuration session you would like
to create -- note that this method raises a
NotImplementedError for platforms that do not support config sessions
register_configuration_session method creates a new privilege level for you and updates the transport class
with the appropriate information internally (see next section). An example of creating a session for an EOS device
called "my-config-session" can be seen here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
1 2 3
Modifying Privilege Levels¶
When creating a configuration session, or modifying a privilege level during runtime, scrapli needs to update some
internal arguments in order to always have a full "map" of how to escalate/deescalate, as well as to be able to
match prompts based on any/all of the patterns available in the privilege levels dictionary. The
register_configuration_session method will automatically handle updating these internal arguments, however if
you modify any of the privilege levels (or add a priv level on the fly without using the register method) then
you will need to manually call the
All examples in this readme have shown using the "core" network drivers such as
IOSXEDriver. These core network
drivers are actually sub-classes of an ABC called
NetworkDriver which itself is a sub-class of the
GenericDriver which is a sub-class of the base
Scrape class -- the namesake for this library. The
Driver object can be used
directly if you prefer to have a much less opinionated or less "auto-magic" type experience.
Driver does not
provide the same
send_configs methods, nor does it disable paging, or handle any
kind of privilege escalation/de-escalation.
Driver is a much more basic "paramiko"-like experience. Below is a
brief example of using the
Driver object directly:
1 2 3 4 5 6 7 8 9 10 11 12
send_command and similar methods, you must directly access the
Channel object when sending inputs
Driver driver directly is nice enough, however you may not want to have to change the prompt pattern, or
deal with accessing the channel to send commands to the device. In this case there is a
GenericDriver available to
you. This driver has a very broad pattern that it matches for base prompts, has no concept of disabling paging or
privilege levels (like
Driver), but does provide
get_prompt methods for a more NetworkDriver-like experience.
GenericDriver can be used as a starting point for devices that don't fall under the core supported
1 2 3 4 5 6 7 8 9 10 11 12 13
Using a Different Transport¶
scrapli is built to be very flexible, including being flexible enough to use different libraries for "transport
" -- or the actual Telnet/SSH communication. By default, scrapli uses the "system" transport which quite literally
uses the ssh binary on your system (
/usr/bin/ssh). This "system" transport means that scrapli has no external
dependencies as it just relies on what is available on the machine running the scrapli script.
In the spirit of being highly flexible, scrapli allows users to swap out this "system" transport with another
transport mechanism. The other supported transport plugins are
asynctelnet. The transport selection can be made when instantiating the
scrapli connection object by passing in
asynctelnet to force scrapli
to use the corresponding transport mechanism. If you are using one of the async transports you must use an async driver!
While it will be a goal to ensure that these other transport mechanisms are supported and useful, the focus of scrapli development will be on the "system" SSH transport.
paramiko as the transport:
1 2 3 4 5 6 7 8 9 10 11 12
Currently, the only reason I can think of to use anything other than "system" as the transport would be to test scrapli on a Windows host, to use telnet, to use ssh2 for super speed, or to use asyncio. If there are other good reasons please do let me know!
NOTE only supported with system and telnet transports!
Some devices, such as Cisco WLC, have no "true" SSH authentication, and instead prompt for credentials (or perhaps
not even that) after session establishment. In order to cope with this corner case, the
auth_bypass flag can be
True which will cause scrapli to skip all authentication steps. Typically, this flag would be set and a
on_open function set to handle whatever prompts the device has upon SSH session establishment.
See the non core device example to see this in action.
Because each transport has different options/features available, it doesn't make sense to try to put all possible
arguments in the
NetworkDriver drivers, to address this an argument
transport_options has been added
. This is exactly what it sounds like -- arguments that can be passed to the selected transport class. As these
arguments will be transport-specific, please check the docs/docstrings for your preferred transport to see what is
A simple example of passing additional SSH arguments to the
SystemSSHTransport class is available
Raise For Status¶
MultiResponse objects both contain a method called
raise_for_status. This method's
purpose is to provide a very simple way to raise an exception if any of the commands or configs sent in a method
1 2 3 4 5 6 7 8 9 10 11 12
responses object from the above example, we can see that it indeed is marked as
Success: False, even
though the first and last commands were successful:
1 2 3 4 5 6 7 8
Finally, we can all the
raise_for_status method to have scrapli raise the
ScrapliCommandFailure exception if any
of the configs/commands failed:
1 2 3 4 5 6