diff --git a/docs/netmiko/arista/arista.html b/docs/netmiko/arista/arista.html
index a426d43ad01115f7c4e9e48b0a1b98a52fe93a9b..02f21848815d10907e08012d7475bd239caadd15 100644
--- a/docs/netmiko/arista/arista.html
+++ b/docs/netmiko/arista/arista.html
@@ -22,21 +22,24 @@
 <section id="section-intro">
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">import time
+<pre><code class="python">import re
 from netmiko.cisco_base_connection import CiscoSSHConnection
 from netmiko.cisco_base_connection import CiscoFileTransfer
 
 
 class AristaBase(CiscoSSHConnection):
+    def __init__(self, *args, **kwargs):
+        kwargs.setdefault(&#34;fast_cli&#34;, True)
+        kwargs.setdefault(&#34;_legacy_mode&#34;, False)
+        return super().__init__(*args, **kwargs)
+
     def session_preparation(self):
         &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        cmd = &#34;terminal width 511&#34;
+        # Arista will echo immediately and then when the device really responds (like NX-OS)
+        self.set_terminal_width(command=cmd, pattern=r&#34;Width set to&#34;)
+        self.disable_paging(cmd_verify=False, pattern=r&#34;Pagination disabled&#34;)
         self.set_base_prompt()
-        self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
-        self.disable_paging()
-        # Clear the read buffer
-        time.sleep(0.3 * self.global_delay_factor)
-        self.clear_buffer()
 
     def check_config_mode(self, check_string=&#34;)#&#34;, pattern=&#34;&#34;):
         &#34;&#34;&#34;
@@ -57,6 +60,20 @@ class AristaBase(CiscoSSHConnection):
         output = output.replace(&#34;(s2)&#34;, &#34;&#34;)
         return check_string in output
 
+    def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;, re_flags=0):
+        &#34;&#34;&#34;Force arista to read pattern all the way to prompt on the next line.&#34;&#34;&#34;
+
+        if not re_flags:
+            re_flags = re.DOTALL
+        check_string = re.escape(&#34;)#&#34;)
+
+        if not pattern:
+            pattern = re.escape(self.base_prompt[:16])
+            pattern = f&#34;{pattern}.*{check_string}&#34;
+        return super().config_mode(
+            config_command=config_command, pattern=pattern, re_flags=re_flags
+        )
+
     def _enter_shell(self):
         &#34;&#34;&#34;Enter the Bourne Shell.&#34;&#34;&#34;
         return self.send_command(&#34;bash&#34;, expect_string=r&#34;[\$#]&#34;)
@@ -143,7 +160,7 @@ class AristaFileTransfer(CiscoFileTransfer):
 <dl>
 <dt id="netmiko.arista.arista.AristaBase"><code class="flex name class">
 <span>class <span class="ident">AristaBase</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Base Class for cisco-like behavior.</p>
@@ -280,15 +297,18 @@ class AristaFileTransfer(CiscoFileTransfer):
 <details class="source">
 <summary>Source code</summary>
 <pre><code class="python">class AristaBase(CiscoSSHConnection):
+    def __init__(self, *args, **kwargs):
+        kwargs.setdefault(&#34;fast_cli&#34;, True)
+        kwargs.setdefault(&#34;_legacy_mode&#34;, False)
+        return super().__init__(*args, **kwargs)
+
     def session_preparation(self):
         &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        cmd = &#34;terminal width 511&#34;
+        # Arista will echo immediately and then when the device really responds (like NX-OS)
+        self.set_terminal_width(command=cmd, pattern=r&#34;Width set to&#34;)
+        self.disable_paging(cmd_verify=False, pattern=r&#34;Pagination disabled&#34;)
         self.set_base_prompt()
-        self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
-        self.disable_paging()
-        # Clear the read buffer
-        time.sleep(0.3 * self.global_delay_factor)
-        self.clear_buffer()
 
     def check_config_mode(self, check_string=&#34;)#&#34;, pattern=&#34;&#34;):
         &#34;&#34;&#34;
@@ -309,6 +329,20 @@ class AristaFileTransfer(CiscoFileTransfer):
         output = output.replace(&#34;(s2)&#34;, &#34;&#34;)
         return check_string in output
 
+    def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;, re_flags=0):
+        &#34;&#34;&#34;Force arista to read pattern all the way to prompt on the next line.&#34;&#34;&#34;
+
+        if not re_flags:
+            re_flags = re.DOTALL
+        check_string = re.escape(&#34;)#&#34;)
+
+        if not pattern:
+            pattern = re.escape(self.base_prompt[:16])
+            pattern = f&#34;{pattern}.*{check_string}&#34;
+        return super().config_mode(
+            config_command=config_command, pattern=pattern, re_flags=re_flags
+        )
+
     def _enter_shell(self):
         &#34;&#34;&#34;Enter the Bourne Shell.&#34;&#34;&#34;
         return self.send_command(&#34;bash&#34;, expect_string=r&#34;[\$#]&#34;)
@@ -360,6 +394,28 @@ loc1-core01(s1)#</p>
     return check_string in output</code></pre>
 </details>
 </dd>
+<dt id="netmiko.arista.arista.AristaBase.config_mode"><code class="name flex">
+<span>def <span class="ident">config_mode</span></span>(<span>self, config_command='configure terminal', pattern='', re_flags=0)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Force arista to read pattern all the way to prompt on the next line.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;, re_flags=0):
+    &#34;&#34;&#34;Force arista to read pattern all the way to prompt on the next line.&#34;&#34;&#34;
+
+    if not re_flags:
+        re_flags = re.DOTALL
+    check_string = re.escape(&#34;)#&#34;)
+
+    if not pattern:
+        pattern = re.escape(self.base_prompt[:16])
+        pattern = f&#34;{pattern}.*{check_string}&#34;
+    return super().config_mode(
+        config_command=config_command, pattern=pattern, re_flags=re_flags
+    )</code></pre>
+</details>
+</dd>
 <dt id="netmiko.arista.arista.AristaBase.session_preparation"><code class="name flex">
 <span>def <span class="ident">session_preparation</span></span>(<span>self)</span>
 </code></dt>
@@ -369,13 +425,11 @@ loc1-core01(s1)#</p>
 <summary>Source code</summary>
 <pre><code class="python">def session_preparation(self):
     &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-    self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
-    self.set_base_prompt()
-    self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
-    self.disable_paging()
-    # Clear the read buffer
-    time.sleep(0.3 * self.global_delay_factor)
-    self.clear_buffer()</code></pre>
+    cmd = &#34;terminal width 511&#34;
+    # Arista will echo immediately and then when the device really responds (like NX-OS)
+    self.set_terminal_width(command=cmd, pattern=r&#34;Width set to&#34;)
+    self.disable_paging(cmd_verify=False, pattern=r&#34;Pagination disabled&#34;)
+    self.set_base_prompt()</code></pre>
 </details>
 </dd>
 </dl>
@@ -388,7 +442,6 @@ loc1-core01(s1)#</p>
 <li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
 <li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
 <li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
-<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li>
 <li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
 <li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
 <li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li>
@@ -519,7 +572,7 @@ loc1-core01(s1)#</p>
 </dd>
 <dt id="netmiko.arista.arista.AristaSSH"><code class="flex name class">
 <span>class <span class="ident">AristaSSH</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Base Class for cisco-like behavior.</p>
@@ -675,7 +728,7 @@ loc1-core01(s1)#</p>
 <li><code><a title="netmiko.arista.arista.AristaBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
-<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="#netmiko.arista.arista.AristaBase.config_mode">config_mode</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li>
@@ -874,7 +927,7 @@ loc1-core01(s1)#</p>
 <li><code><a title="netmiko.arista.arista.AristaBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
-<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="#netmiko.arista.arista.AristaBase.config_mode">config_mode</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li>
@@ -932,6 +985,7 @@ loc1-core01(s1)#</p>
 <h4><code><a title="netmiko.arista.arista.AristaBase" href="#netmiko.arista.arista.AristaBase">AristaBase</a></code></h4>
 <ul class="">
 <li><code><a title="netmiko.arista.arista.AristaBase.check_config_mode" href="#netmiko.arista.arista.AristaBase.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="#netmiko.arista.arista.AristaBase.config_mode">config_mode</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.session_preparation" href="#netmiko.arista.arista.AristaBase.session_preparation">session_preparation</a></code></li>
 </ul>
 </li>
diff --git a/docs/netmiko/arista/index.html b/docs/netmiko/arista/index.html
index e5e8d4f774a150aac03c2788532675dd7987230a..f68d8cd46bca55fbb342cbea7f32b92de091adf3 100644
--- a/docs/netmiko/arista/index.html
+++ b/docs/netmiko/arista/index.html
@@ -137,7 +137,7 @@ __all__ = [&#34;AristaSSH&#34;, &#34;AristaTelnet&#34;, &#34;AristaFileTransfer&
 </dd>
 <dt id="netmiko.arista.AristaSSH"><code class="flex name class">
 <span>class <span class="ident">AristaSSH</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Base Class for cisco-like behavior.</p>
@@ -293,7 +293,7 @@ __all__ = [&#34;AristaSSH&#34;, &#34;AristaTelnet&#34;, &#34;AristaFileTransfer&
 <li><code><a title="netmiko.arista.arista.AristaBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
-<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="arista.html#netmiko.arista.arista.AristaBase.config_mode">config_mode</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li>
@@ -492,7 +492,7 @@ __all__ = [&#34;AristaSSH&#34;, &#34;AristaTelnet&#34;, &#34;AristaFileTransfer&
 <li><code><a title="netmiko.arista.arista.AristaBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
-<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.arista.arista.AristaBase.config_mode" href="arista.html#netmiko.arista.arista.AristaBase.config_mode">config_mode</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
 <li><code><a title="netmiko.arista.arista.AristaBase.enable" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.enable">enable</a></code></li>
diff --git a/docs/netmiko/aruba/aruba_ssh.html b/docs/netmiko/aruba/aruba_ssh.html
index 1a254b0c3f6e416be36cd98e124d34e8d51a7a30..4ff52af1dc78ce59cc62c7854eaad4e06f964185 100644
--- a/docs/netmiko/aruba/aruba_ssh.html
+++ b/docs/netmiko/aruba/aruba_ssh.html
@@ -5,7 +5,7 @@
 <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
 <meta name="generator" content="pdoc 0.6.3" />
 <title>netmiko.aruba.aruba_ssh API documentation</title>
-<meta name="description" content="Aruba OS support" />
+<meta name="description" content="Aruba OS support …" />
 <link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
 <link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
 <link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
@@ -20,10 +20,16 @@
 <h1 class="title">Module <code>netmiko.aruba.aruba_ssh</code></h1>
 </header>
 <section id="section-intro">
-<p>Aruba OS support</p>
+<p>Aruba OS support.</p>
+<p>For use with Aruba OS Controllers.</p>
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">&#34;&#34;&#34;Aruba OS support&#34;&#34;&#34;
+<pre><code class="python">&#34;&#34;&#34;
+Aruba OS support.
+
+For use with Aruba OS Controllers.
+
+&#34;&#34;&#34;
 import time
 import re
 from netmiko.cisco_base_connection import CiscoSSHConnection
diff --git a/docs/netmiko/aruba/index.html b/docs/netmiko/aruba/index.html
index b8076d60d97d4a7f163a0277ba104d6bd40c5cd6..7b5031e92f5db554727d24053fae053a6183ed87 100644
--- a/docs/netmiko/aruba/index.html
+++ b/docs/netmiko/aruba/index.html
@@ -32,7 +32,7 @@ __all__ = [&#34;ArubaSSH&#34;]</code></pre>
 <dl>
 <dt><code class="name"><a title="netmiko.aruba.aruba_ssh" href="aruba_ssh.html">netmiko.aruba.aruba_ssh</a></code></dt>
 <dd>
-<section class="desc"><p>Aruba OS support</p></section>
+<section class="desc"><p>Aruba OS support …</p></section>
 </dd>
 </dl>
 </section>
diff --git a/docs/netmiko/base_connection.html b/docs/netmiko/base_connection.html
index 8ddfbbba00f5a65de29dffc090284102de7f845a..8905871016385c5eb700e88051c5983808957960 100644
--- a/docs/netmiko/base_connection.html
+++ b/docs/netmiko/base_connection.html
@@ -45,6 +45,7 @@ from threading import Lock
 
 import paramiko
 import serial
+from tenacity import retry, stop_after_attempt, wait_exponential
 
 from netmiko import log
 from netmiko.netmiko_globals import MAX_BUFFER, BACKSPACE_CHAR
@@ -57,6 +58,7 @@ from netmiko.utilities import (
     check_serial_port,
     get_structured_data,
     get_structured_data_genie,
+    get_structured_data_ttp,
     select_cmd_verify,
 )
 from netmiko.utilities import m_exec_time  # noqa
@@ -1008,6 +1010,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 print(&#34;Interactive SSH session established&#34;)
         return &#34;&#34;
 
+    # @m_exec_time
     def _test_channel_read(self, count=40, pattern=&#34;&#34;):
         &#34;&#34;&#34;Try to read the channel (generally post login) verify you receive data back.
 
@@ -1039,6 +1042,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 break
             else:
                 self.write_channel(self.RETURN)
+
             main_delay = _increment_delay(main_delay)
             time.sleep(main_delay)
             i += 1
@@ -1073,7 +1077,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
         :type delay_factor: int
         &#34;&#34;&#34;
         if self.fast_cli:
-            if delay_factor &lt;= self.global_delay_factor:
+            if delay_factor and delay_factor &lt;= self.global_delay_factor:
                 return delay_factor
             else:
                 return self.global_delay_factor
@@ -1142,6 +1146,10 @@ Device settings: {self.device_type} {self.host}:{self.port}
             output = self.read_until_prompt()
         return output
 
+    # Retry by sleeping .33 and then double sleep until 5 attempts (.33, .66, 1.32, etc)
+    @retry(
+        wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5)
+    )
     def set_base_prompt(
         self, pri_prompt_terminator=&#34;#&#34;, alt_prompt_terminator=&#34;&gt;&#34;, delay_factor=1
     ):
@@ -1236,6 +1244,8 @@ Device settings: {self.device_type} {self.host}:{self.port}
         normalize=True,
         use_textfsm=False,
         textfsm_template=None,
+        use_ttp=False,
+        ttp_template=None,
         use_genie=False,
         cmd_verify=False,
         cmd_echo=None,
@@ -1269,6 +1279,13 @@ Device settings: {self.device_type} {self.host}:{self.port}
             path, relative path, or name of file in current directory. (default: None).
         :type textfsm_template: str
 
+        :param use_ttp: Process command output through TTP template (default: False).
+        :type use_ttp: bool
+
+        :param ttp_template: Name of template to parse output with; can be fully qualified
+            path, relative path, or name of file in current directory. (default: None).
+        :type ttp_template: str
+
         :param use_genie: Process command output through PyATS/Genie parser (default: False).
         :type use_genie: bool
 
@@ -1278,13 +1295,19 @@ Device settings: {self.device_type} {self.host}:{self.port}
         :param cmd_echo: Deprecated (use cmd_verify instead)
         :type cmd_echo: bool
         &#34;&#34;&#34;
-        # For compatibility remove cmd_echo in Netmiko 4.x.x
+
+        # For compatibility; remove cmd_echo in Netmiko 4.x.x
         if cmd_echo is not None:
             cmd_verify = cmd_echo
 
         output = &#34;&#34;
+
         delay_factor = self.select_delay_factor(delay_factor)
-        self.clear_buffer()
+        # Cleanup in future versions of Netmiko
+        if delay_factor &lt; 1:
+            if not self._legacy_mode and self.fast_cli:
+                delay_factor = 1
+
         if normalize:
             command_string = self.normalize_cmd(command_string)
 
@@ -1319,7 +1342,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             strip_prompt=strip_prompt,
         )
 
-        # If both TextFSM and Genie are set, try TextFSM then Genie
+        # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
         if use_textfsm:
             structured_output = get_structured_data(
                 output,
@@ -1330,6 +1353,11 @@ Device settings: {self.device_type} {self.host}:{self.port}
             # If we have structured data; return it.
             if not isinstance(structured_output, str):
                 return structured_output
+        if use_ttp:
+            structured_output = get_structured_data_ttp(output, template=ttp_template)
+            # If we have structured data; return it.
+            if not isinstance(structured_output, str):
+                return structured_output
         if use_genie:
             structured_output = get_structured_data_genie(
                 output, platform=self.device_type, command=command_string.strip()
@@ -1394,6 +1422,8 @@ Device settings: {self.device_type} {self.host}:{self.port}
         normalize=True,
         use_textfsm=False,
         textfsm_template=None,
+        use_ttp=False,
+        ttp_template=None,
         use_genie=False,
         cmd_verify=True,
     ):
@@ -1431,6 +1461,13 @@ Device settings: {self.device_type} {self.host}:{self.port}
         :param textfsm_template: Name of template to parse output with; can be fully qualified
             path, relative path, or name of file in current directory. (default: None).
 
+        :param use_ttp: Process command output through TTP template (default: False).
+        :type use_ttp: bool
+
+        :param ttp_template: Name of template to parse output with; can be fully qualified
+            path, relative path, or name of file in current directory. (default: None).
+        :type ttp_template: str
+
         :param use_genie: Process command output through PyATS/Genie parser (default: False).
         :type normalize: bool
 
@@ -1512,7 +1549,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             new_data = self.read_channel()
         else:  # nobreak
             raise IOError(
-                &#34;Search pattern never detected in send_command_expect: {}&#34;.format(
+                &#34;Search pattern never detected in send_command: {}&#34;.format(
                     search_pattern
                 )
             )
@@ -1524,7 +1561,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             strip_prompt=strip_prompt,
         )
 
-        # If both TextFSM and Genie are set, try TextFSM then Genie
+        # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
         if use_textfsm:
             structured_output = get_structured_data(
                 output,
@@ -1535,6 +1572,11 @@ Device settings: {self.device_type} {self.host}:{self.port}
             # If we have structured data; return it.
             if not isinstance(structured_output, str):
                 return structured_output
+        if use_ttp:
+            structured_output = get_structured_data_ttp(output, template=ttp_template)
+            # If we have structured data; return it.
+            if not isinstance(structured_output, str):
+                return structured_output
         if use_genie:
             structured_output = get_structured_data_genie(
                 output, platform=self.device_type, command=command_string.strip()
@@ -1691,7 +1733,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             output = self.read_until_pattern(pattern=pattern)
         return check_string in output
 
-    def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;):
+    def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;, re_flags=0):
         &#34;&#34;&#34;Enter into config_mode.
 
         :param config_command: Configuration command to send to the device
@@ -1699,6 +1741,9 @@ Device settings: {self.device_type} {self.host}:{self.port}
 
         :param pattern: Pattern to terminate reading of channel
         :type pattern: str
+
+        :param re_flags: Regular expression flags
+        :type re_flags: RegexFlag
         &#34;&#34;&#34;
         output = &#34;&#34;
         if not self.check_config_mode():
@@ -1708,8 +1753,8 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 output += self.read_until_pattern(
                     pattern=re.escape(config_command.strip())
                 )
-            if not re.search(pattern, output, flags=re.M):
-                output += self.read_until_pattern(pattern=pattern)
+            if not re.search(pattern, output, flags=re_flags):
+                output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
             if not self.check_config_mode():
                 raise ValueError(&#34;Failed to enter configuration mode.&#34;)
         return output
@@ -3102,6 +3147,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 print(&#34;Interactive SSH session established&#34;)
         return &#34;&#34;
 
+    # @m_exec_time
     def _test_channel_read(self, count=40, pattern=&#34;&#34;):
         &#34;&#34;&#34;Try to read the channel (generally post login) verify you receive data back.
 
@@ -3133,6 +3179,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 break
             else:
                 self.write_channel(self.RETURN)
+
             main_delay = _increment_delay(main_delay)
             time.sleep(main_delay)
             i += 1
@@ -3167,7 +3214,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
         :type delay_factor: int
         &#34;&#34;&#34;
         if self.fast_cli:
-            if delay_factor &lt;= self.global_delay_factor:
+            if delay_factor and delay_factor &lt;= self.global_delay_factor:
                 return delay_factor
             else:
                 return self.global_delay_factor
@@ -3236,6 +3283,10 @@ Device settings: {self.device_type} {self.host}:{self.port}
             output = self.read_until_prompt()
         return output
 
+    # Retry by sleeping .33 and then double sleep until 5 attempts (.33, .66, 1.32, etc)
+    @retry(
+        wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5)
+    )
     def set_base_prompt(
         self, pri_prompt_terminator=&#34;#&#34;, alt_prompt_terminator=&#34;&gt;&#34;, delay_factor=1
     ):
@@ -3330,6 +3381,8 @@ Device settings: {self.device_type} {self.host}:{self.port}
         normalize=True,
         use_textfsm=False,
         textfsm_template=None,
+        use_ttp=False,
+        ttp_template=None,
         use_genie=False,
         cmd_verify=False,
         cmd_echo=None,
@@ -3363,6 +3416,13 @@ Device settings: {self.device_type} {self.host}:{self.port}
             path, relative path, or name of file in current directory. (default: None).
         :type textfsm_template: str
 
+        :param use_ttp: Process command output through TTP template (default: False).
+        :type use_ttp: bool
+
+        :param ttp_template: Name of template to parse output with; can be fully qualified
+            path, relative path, or name of file in current directory. (default: None).
+        :type ttp_template: str
+
         :param use_genie: Process command output through PyATS/Genie parser (default: False).
         :type use_genie: bool
 
@@ -3372,13 +3432,19 @@ Device settings: {self.device_type} {self.host}:{self.port}
         :param cmd_echo: Deprecated (use cmd_verify instead)
         :type cmd_echo: bool
         &#34;&#34;&#34;
-        # For compatibility remove cmd_echo in Netmiko 4.x.x
+
+        # For compatibility; remove cmd_echo in Netmiko 4.x.x
         if cmd_echo is not None:
             cmd_verify = cmd_echo
 
         output = &#34;&#34;
+
         delay_factor = self.select_delay_factor(delay_factor)
-        self.clear_buffer()
+        # Cleanup in future versions of Netmiko
+        if delay_factor &lt; 1:
+            if not self._legacy_mode and self.fast_cli:
+                delay_factor = 1
+
         if normalize:
             command_string = self.normalize_cmd(command_string)
 
@@ -3413,7 +3479,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             strip_prompt=strip_prompt,
         )
 
-        # If both TextFSM and Genie are set, try TextFSM then Genie
+        # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
         if use_textfsm:
             structured_output = get_structured_data(
                 output,
@@ -3424,6 +3490,11 @@ Device settings: {self.device_type} {self.host}:{self.port}
             # If we have structured data; return it.
             if not isinstance(structured_output, str):
                 return structured_output
+        if use_ttp:
+            structured_output = get_structured_data_ttp(output, template=ttp_template)
+            # If we have structured data; return it.
+            if not isinstance(structured_output, str):
+                return structured_output
         if use_genie:
             structured_output = get_structured_data_genie(
                 output, platform=self.device_type, command=command_string.strip()
@@ -3488,6 +3559,8 @@ Device settings: {self.device_type} {self.host}:{self.port}
         normalize=True,
         use_textfsm=False,
         textfsm_template=None,
+        use_ttp=False,
+        ttp_template=None,
         use_genie=False,
         cmd_verify=True,
     ):
@@ -3525,6 +3598,13 @@ Device settings: {self.device_type} {self.host}:{self.port}
         :param textfsm_template: Name of template to parse output with; can be fully qualified
             path, relative path, or name of file in current directory. (default: None).
 
+        :param use_ttp: Process command output through TTP template (default: False).
+        :type use_ttp: bool
+
+        :param ttp_template: Name of template to parse output with; can be fully qualified
+            path, relative path, or name of file in current directory. (default: None).
+        :type ttp_template: str
+
         :param use_genie: Process command output through PyATS/Genie parser (default: False).
         :type normalize: bool
 
@@ -3606,7 +3686,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             new_data = self.read_channel()
         else:  # nobreak
             raise IOError(
-                &#34;Search pattern never detected in send_command_expect: {}&#34;.format(
+                &#34;Search pattern never detected in send_command: {}&#34;.format(
                     search_pattern
                 )
             )
@@ -3618,7 +3698,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             strip_prompt=strip_prompt,
         )
 
-        # If both TextFSM and Genie are set, try TextFSM then Genie
+        # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
         if use_textfsm:
             structured_output = get_structured_data(
                 output,
@@ -3629,6 +3709,11 @@ Device settings: {self.device_type} {self.host}:{self.port}
             # If we have structured data; return it.
             if not isinstance(structured_output, str):
                 return structured_output
+        if use_ttp:
+            structured_output = get_structured_data_ttp(output, template=ttp_template)
+            # If we have structured data; return it.
+            if not isinstance(structured_output, str):
+                return structured_output
         if use_genie:
             structured_output = get_structured_data_genie(
                 output, platform=self.device_type, command=command_string.strip()
@@ -3785,7 +3870,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             output = self.read_until_pattern(pattern=pattern)
         return check_string in output
 
-    def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;):
+    def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;, re_flags=0):
         &#34;&#34;&#34;Enter into config_mode.
 
         :param config_command: Configuration command to send to the device
@@ -3793,6 +3878,9 @@ Device settings: {self.device_type} {self.host}:{self.port}
 
         :param pattern: Pattern to terminate reading of channel
         :type pattern: str
+
+        :param re_flags: Regular expression flags
+        :type re_flags: RegexFlag
         &#34;&#34;&#34;
         output = &#34;&#34;
         if not self.check_config_mode():
@@ -3802,8 +3890,8 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 output += self.read_until_pattern(
                     pattern=re.escape(config_command.strip())
                 )
-            if not re.search(pattern, output, flags=re.M):
-                output += self.read_until_pattern(pattern=pattern)
+            if not re.search(pattern, output, flags=re_flags):
+                output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
             if not self.check_config_mode():
                 raise ValueError(&#34;Failed to enter configuration mode.&#34;)
         return output
@@ -4254,17 +4342,19 @@ def strip_backspaces(output):
 </details>
 </dd>
 <dt id="netmiko.base_connection.BaseConnection.config_mode"><code class="name flex">
-<span>def <span class="ident">config_mode</span></span>(<span>self, config_command='', pattern='')</span>
+<span>def <span class="ident">config_mode</span></span>(<span>self, config_command='', pattern='', re_flags=0)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter into config_mode.</p>
 <p>:param config_command: Configuration command to send to the device
 :type config_command: str</p>
 <p>:param pattern: Pattern to terminate reading of channel
-:type pattern: str</p></section>
+:type pattern: str</p>
+<p>:param re_flags: Regular expression flags
+:type re_flags: RegexFlag</p></section>
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;):
+<pre><code class="python">def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;, re_flags=0):
     &#34;&#34;&#34;Enter into config_mode.
 
     :param config_command: Configuration command to send to the device
@@ -4272,6 +4362,9 @@ def strip_backspaces(output):
 
     :param pattern: Pattern to terminate reading of channel
     :type pattern: str
+
+    :param re_flags: Regular expression flags
+    :type re_flags: RegexFlag
     &#34;&#34;&#34;
     output = &#34;&#34;
     if not self.check_config_mode():
@@ -4281,8 +4374,8 @@ def strip_backspaces(output):
             output += self.read_until_pattern(
                 pattern=re.escape(config_command.strip())
             )
-        if not re.search(pattern, output, flags=re.M):
-            output += self.read_until_pattern(pattern=pattern)
+        if not re.search(pattern, output, flags=re_flags):
+            output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
         if not self.check_config_mode():
             raise ValueError(&#34;Failed to enter configuration mode.&#34;)
     return output</code></pre>
@@ -4354,7 +4447,7 @@ def strip_backspaces(output):
 </details>
 </dd>
 <dt id="netmiko.base_connection.BaseConnection.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='', pattern='ssword', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter enable mode.</p>
@@ -4839,7 +4932,7 @@ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.</p>
     :type delay_factor: int
     &#34;&#34;&#34;
     if self.fast_cli:
-        if delay_factor &lt;= self.global_delay_factor:
+        if delay_factor and delay_factor &lt;= self.global_delay_factor:
             return delay_factor
         else:
             return self.global_delay_factor
@@ -4851,7 +4944,7 @@ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.</p>
 </details>
 </dd>
 <dt id="netmiko.base_connection.BaseConnection.send_command"><code class="name flex">
-<span>def <span class="ident">send_command</span></span>(<span>self, command_string, expect_string=None, delay_factor=1, max_loops=500, auto_find_prompt=True, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_genie=False, cmd_verify=True)</span>
+<span>def <span class="ident">send_command</span></span>(<span>self, command_string, expect_string=None, delay_factor=1, max_loops=500, auto_find_prompt=True, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_ttp=False, ttp_template=None, use_genie=False, cmd_verify=True)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Execute command_string on the SSH channel using a pattern-based mechanism. Generally
@@ -4878,6 +4971,11 @@ based upon self.timeout.
 :type normalize: bool</p>
 <p>:param textfsm_template: Name of template to parse output with; can be fully qualified
 path, relative path, or name of file in current directory. (default: None).</p>
+<p>:param use_ttp: Process command output through TTP template (default: False).
+:type use_ttp: bool</p>
+<p>:param ttp_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:type ttp_template: str</p>
 <p>:param use_genie: Process command output through PyATS/Genie parser (default: False).
 :type normalize: bool</p>
 <p>:param cmd_verify: Verify command echo before proceeding (default: True).
@@ -4897,6 +4995,8 @@ def send_command(
     normalize=True,
     use_textfsm=False,
     textfsm_template=None,
+    use_ttp=False,
+    ttp_template=None,
     use_genie=False,
     cmd_verify=True,
 ):
@@ -4934,6 +5034,13 @@ def send_command(
     :param textfsm_template: Name of template to parse output with; can be fully qualified
         path, relative path, or name of file in current directory. (default: None).
 
+    :param use_ttp: Process command output through TTP template (default: False).
+    :type use_ttp: bool
+
+    :param ttp_template: Name of template to parse output with; can be fully qualified
+        path, relative path, or name of file in current directory. (default: None).
+    :type ttp_template: str
+
     :param use_genie: Process command output through PyATS/Genie parser (default: False).
     :type normalize: bool
 
@@ -5015,7 +5122,7 @@ def send_command(
         new_data = self.read_channel()
     else:  # nobreak
         raise IOError(
-            &#34;Search pattern never detected in send_command_expect: {}&#34;.format(
+            &#34;Search pattern never detected in send_command: {}&#34;.format(
                 search_pattern
             )
         )
@@ -5027,7 +5134,7 @@ def send_command(
         strip_prompt=strip_prompt,
     )
 
-    # If both TextFSM and Genie are set, try TextFSM then Genie
+    # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
     if use_textfsm:
         structured_output = get_structured_data(
             output,
@@ -5038,6 +5145,11 @@ def send_command(
         # If we have structured data; return it.
         if not isinstance(structured_output, str):
             return structured_output
+    if use_ttp:
+        structured_output = get_structured_data_ttp(output, template=ttp_template)
+        # If we have structured data; return it.
+        if not isinstance(structured_output, str):
+            return structured_output
     if use_genie:
         structured_output = get_structured_data_genie(
             output, platform=self.device_type, command=command_string.strip()
@@ -5072,7 +5184,7 @@ def send_command(
 </details>
 </dd>
 <dt id="netmiko.base_connection.BaseConnection.send_command_timing"><code class="name flex">
-<span>def <span class="ident">send_command_timing</span></span>(<span>self, command_string, delay_factor=1, max_loops=150, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_genie=False, cmd_verify=False, cmd_echo=None)</span>
+<span>def <span class="ident">send_command_timing</span></span>(<span>self, command_string, delay_factor=1, max_loops=150, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_ttp=False, ttp_template=None, use_genie=False, cmd_verify=False, cmd_echo=None)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Execute command_string on the SSH channel using a delay-based mechanism. Generally
@@ -5095,6 +5207,11 @@ based upon self.timeout.
 <p>:param textfsm_template: Name of template to parse output with; can be fully qualified
 path, relative path, or name of file in current directory. (default: None).
 :type textfsm_template: str</p>
+<p>:param use_ttp: Process command output through TTP template (default: False).
+:type use_ttp: bool</p>
+<p>:param ttp_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:type ttp_template: str</p>
 <p>:param use_genie: Process command output through PyATS/Genie parser (default: False).
 :type use_genie: bool</p>
 <p>:param cmd_verify: Verify command echo before proceeding (default: False).
@@ -5114,6 +5231,8 @@ def send_command_timing(
     normalize=True,
     use_textfsm=False,
     textfsm_template=None,
+    use_ttp=False,
+    ttp_template=None,
     use_genie=False,
     cmd_verify=False,
     cmd_echo=None,
@@ -5147,6 +5266,13 @@ def send_command_timing(
         path, relative path, or name of file in current directory. (default: None).
     :type textfsm_template: str
 
+    :param use_ttp: Process command output through TTP template (default: False).
+    :type use_ttp: bool
+
+    :param ttp_template: Name of template to parse output with; can be fully qualified
+        path, relative path, or name of file in current directory. (default: None).
+    :type ttp_template: str
+
     :param use_genie: Process command output through PyATS/Genie parser (default: False).
     :type use_genie: bool
 
@@ -5156,13 +5282,19 @@ def send_command_timing(
     :param cmd_echo: Deprecated (use cmd_verify instead)
     :type cmd_echo: bool
     &#34;&#34;&#34;
-    # For compatibility remove cmd_echo in Netmiko 4.x.x
+
+    # For compatibility; remove cmd_echo in Netmiko 4.x.x
     if cmd_echo is not None:
         cmd_verify = cmd_echo
 
     output = &#34;&#34;
+
     delay_factor = self.select_delay_factor(delay_factor)
-    self.clear_buffer()
+    # Cleanup in future versions of Netmiko
+    if delay_factor &lt; 1:
+        if not self._legacy_mode and self.fast_cli:
+            delay_factor = 1
+
     if normalize:
         command_string = self.normalize_cmd(command_string)
 
@@ -5197,7 +5329,7 @@ def send_command_timing(
         strip_prompt=strip_prompt,
     )
 
-    # If both TextFSM and Genie are set, try TextFSM then Genie
+    # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
     if use_textfsm:
         structured_output = get_structured_data(
             output,
@@ -5208,6 +5340,11 @@ def send_command_timing(
         # If we have structured data; return it.
         if not isinstance(structured_output, str):
             return structured_output
+    if use_ttp:
+        structured_output = get_structured_data_ttp(output, template=ttp_template)
+        # If we have structured data; return it.
+        if not isinstance(structured_output, str):
+            return structured_output
     if use_genie:
         structured_output = get_structured_data_genie(
             output, platform=self.device_type, command=command_string.strip()
@@ -5466,7 +5603,10 @@ entering/exiting config mode.</p>
 :type delay_factor: int</p></section>
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">def set_base_prompt(
+<pre><code class="python">@retry(
+    wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5)
+)
+def set_base_prompt(
     self, pri_prompt_terminator=&#34;#&#34;, alt_prompt_terminator=&#34;&gt;&#34;, delay_factor=1
 ):
     &#34;&#34;&#34;Sets self.base_prompt
diff --git a/docs/netmiko/cisco/cisco_ftd_ssh.html b/docs/netmiko/cisco/cisco_ftd_ssh.html
new file mode 100644
index 0000000000000000000000000000000000000000..ca075cf96af2831313288d3ac307a065f62e9666
--- /dev/null
+++ b/docs/netmiko/cisco/cisco_ftd_ssh.html
@@ -0,0 +1,376 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.6.3" />
+<title>netmiko.cisco.cisco_ftd_ssh API documentation</title>
+<meta name="description" content="Subclass specific to Cisco FTD." />
+<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
+<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
+<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
+<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>netmiko.cisco.cisco_ftd_ssh</code></h1>
+</header>
+<section id="section-intro">
+<p>Subclass specific to Cisco FTD.</p>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">&#34;&#34;&#34;Subclass specific to Cisco FTD.&#34;&#34;&#34;
+from netmiko.cisco_base_connection import CiscoSSHConnection
+
+
+class CiscoFtdSSH(CiscoSSHConnection):
+    &#34;&#34;&#34;Subclass specific to Cisco FTD.&#34;&#34;&#34;
+
+    def session_preparation(self):
+        &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
+        self._test_channel_read()
+        self.set_base_prompt()
+
+    def send_config_set(self, *args, **kwargs):
+        &#34;&#34;&#34;Canot change config on FTD via ssh&#34;&#34;&#34;
+        raise NotImplementedError
+
+    def enable(self, *args, **kwargs):
+        &#34;&#34;&#34;No enable mode on firepower ssh&#34;&#34;&#34;
+        return &#34;&#34;
+
+    def config_mode(self, *args, **kwargs):
+        &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+        return &#34;&#34;
+
+    def check_config_mode(self, *args, **kwargs):
+        &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+        return False</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-classes">Classes</h2>
+<dl>
+<dt id="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH"><code class="flex name class">
+<span>class <span class="ident">CiscoFtdSSH</span></span>
+<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Subclass specific to Cisco FTD.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class CiscoFtdSSH(CiscoSSHConnection):
+    &#34;&#34;&#34;Subclass specific to Cisco FTD.&#34;&#34;&#34;
+
+    def session_preparation(self):
+        &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
+        self._test_channel_read()
+        self.set_base_prompt()
+
+    def send_config_set(self, *args, **kwargs):
+        &#34;&#34;&#34;Canot change config on FTD via ssh&#34;&#34;&#34;
+        raise NotImplementedError
+
+    def enable(self, *args, **kwargs):
+        &#34;&#34;&#34;No enable mode on firepower ssh&#34;&#34;&#34;
+        return &#34;&#34;
+
+    def config_mode(self, *args, **kwargs):
+        &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+        return &#34;&#34;
+
+    def check_config_mode(self, *args, **kwargs):
+        &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+        return False</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Methods</h3>
+<dl>
+<dt id="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.check_config_mode"><code class="name flex">
+<span>def <span class="ident">check_config_mode</span></span>(<span>self, *args, **kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>No config mode on firepower ssh</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def check_config_mode(self, *args, **kwargs):
+    &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+    return False</code></pre>
+</details>
+</dd>
+<dt id="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.config_mode"><code class="name flex">
+<span>def <span class="ident">config_mode</span></span>(<span>self, *args, **kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>No config mode on firepower ssh</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def config_mode(self, *args, **kwargs):
+    &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+    return &#34;&#34;</code></pre>
+</details>
+</dd>
+<dt id="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.enable"><code class="name flex">
+<span>def <span class="ident">enable</span></span>(<span>self, *args, **kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>No enable mode on firepower ssh</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def enable(self, *args, **kwargs):
+    &#34;&#34;&#34;No enable mode on firepower ssh&#34;&#34;&#34;
+    return &#34;&#34;</code></pre>
+</details>
+</dd>
+<dt id="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.send_config_set"><code class="name flex">
+<span>def <span class="ident">send_config_set</span></span>(<span>self, *args, **kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Canot change config on FTD via ssh</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def send_config_set(self, *args, **kwargs):
+    &#34;&#34;&#34;Canot change config on FTD via ssh&#34;&#34;&#34;
+    raise NotImplementedError</code></pre>
+</details>
+</dd>
+<dt id="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.session_preparation"><code class="name flex">
+<span>def <span class="ident">session_preparation</span></span>(<span>self)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Prepare the session after the connection has been established.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def session_preparation(self):
+    &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
+    self._test_channel_read()
+    self.set_base_prompt()</code></pre>
+</details>
+</dd>
+</dl>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_base_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_base_prompt">set_base_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
+</dl>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="netmiko.cisco" href="index.html">netmiko.cisco</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-classes">Classes</a></h3>
+<ul>
+<li>
+<h4><code><a title="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH" href="#netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH">CiscoFtdSSH</a></code></h4>
+<ul class="">
+<li><code><a title="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.check_config_mode" href="#netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.config_mode" href="#netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.enable" href="#netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.enable">enable</a></code></li>
+<li><code><a title="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.send_config_set" href="#netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.session_preparation" href="#netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH.session_preparation">session_preparation</a></code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p>
+</footer>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
+<script>hljs.initHighlightingOnLoad()</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/netmiko/cisco/cisco_nxos_ssh.html b/docs/netmiko/cisco/cisco_nxos_ssh.html
index 64c718dbe01d0a487d880259a7485b64229644f6..696572719a844d05d3725247fe6f33d9d5c72f91 100644
--- a/docs/netmiko/cisco/cisco_nxos_ssh.html
+++ b/docs/netmiko/cisco/cisco_nxos_ssh.html
@@ -23,23 +23,28 @@
 <details class="source">
 <summary>Source code</summary>
 <pre><code class="python">import re
-import time
 import os
 from netmiko.cisco_base_connection import CiscoSSHConnection
 from netmiko.cisco_base_connection import CiscoFileTransfer
 
 
 class CiscoNxosSSH(CiscoSSHConnection):
+    def __init__(self, *args, **kwargs):
+        # Cisco NX-OS defaults to fast_cli=True and legacy_mode=False
+        kwargs.setdefault(&#34;fast_cli&#34;, True)
+        kwargs.setdefault(&#34;_legacy_mode&#34;, False)
+        return super().__init__(*args, **kwargs)
+
     def session_preparation(self):
         &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
         self.ansi_escape_codes = True
-        self.set_base_prompt()
-        self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
+        # NX-OS has an issue where it echoes the command even though it hasn&#39;t returned the prompt
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        self.set_terminal_width(
+            command=&#34;terminal width 511&#34;, pattern=r&#34;terminal width 511&#34;
+        )
         self.disable_paging()
-        # Clear the read buffer
-        time.sleep(0.3 * self.global_delay_factor)
-        self.clear_buffer()
+        self.set_base_prompt()
 
     def normalize_linefeeds(self, a_string):
         &#34;&#34;&#34;Convert &#39;\r\n&#39; or &#39;\r\r\n&#39; to &#39;\n, and remove extra &#39;\r&#39;s in the text.&#34;&#34;&#34;
@@ -313,7 +318,7 @@ def process_md5(md5_output, pattern=r&#34;= (.*)&#34;):
 </dd>
 <dt id="netmiko.cisco.cisco_nxos_ssh.CiscoNxosSSH"><code class="flex name class">
 <span>class <span class="ident">CiscoNxosSSH</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Base Class for cisco-like behavior.</p>
@@ -450,16 +455,22 @@ def process_md5(md5_output, pattern=r&#34;= (.*)&#34;):
 <details class="source">
 <summary>Source code</summary>
 <pre><code class="python">class CiscoNxosSSH(CiscoSSHConnection):
+    def __init__(self, *args, **kwargs):
+        # Cisco NX-OS defaults to fast_cli=True and legacy_mode=False
+        kwargs.setdefault(&#34;fast_cli&#34;, True)
+        kwargs.setdefault(&#34;_legacy_mode&#34;, False)
+        return super().__init__(*args, **kwargs)
+
     def session_preparation(self):
         &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
         self.ansi_escape_codes = True
-        self.set_base_prompt()
-        self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
+        # NX-OS has an issue where it echoes the command even though it hasn&#39;t returned the prompt
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        self.set_terminal_width(
+            command=&#34;terminal width 511&#34;, pattern=r&#34;terminal width 511&#34;
+        )
         self.disable_paging()
-        # Clear the read buffer
-        time.sleep(0.3 * self.global_delay_factor)
-        self.clear_buffer()
+        self.set_base_prompt()
 
     def normalize_linefeeds(self, a_string):
         &#34;&#34;&#34;Convert &#39;\r\n&#39; or &#39;\r\r\n&#39; to &#39;\n, and remove extra &#39;\r&#39;s in the text.&#34;&#34;&#34;
@@ -518,14 +529,14 @@ def process_md5(md5_output, pattern=r&#34;= (.*)&#34;):
 <summary>Source code</summary>
 <pre><code class="python">def session_preparation(self):
     &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-    self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
     self.ansi_escape_codes = True
-    self.set_base_prompt()
-    self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
+    # NX-OS has an issue where it echoes the command even though it hasn&#39;t returned the prompt
+    self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+    self.set_terminal_width(
+        command=&#34;terminal width 511&#34;, pattern=r&#34;terminal width 511&#34;
+    )
     self.disable_paging()
-    # Clear the read buffer
-    time.sleep(0.3 * self.global_delay_factor)
-    self.clear_buffer()</code></pre>
+    self.set_base_prompt()</code></pre>
 </details>
 </dd>
 </dl>
diff --git a/docs/netmiko/cisco/cisco_xr.html b/docs/netmiko/cisco/cisco_xr.html
index 1c35a8e30439d91a7ca09872e1c553b34e91b9da..f590b5480afeeb6a36ddbed73cc5a6f7ce65b917 100644
--- a/docs/netmiko/cisco/cisco_xr.html
+++ b/docs/netmiko/cisco/cisco_xr.html
@@ -22,25 +22,30 @@
 <section id="section-intro">
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">import time
-import re
+<pre><code class="python">import re
 from netmiko.cisco_base_connection import CiscoBaseConnection, CiscoFileTransfer
 
 
 class CiscoXrBase(CiscoBaseConnection):
+    def __init__(self, *args, **kwargs):
+        # Cisco NX-OS defaults to fast_cli=True and legacy_mode=False
+        kwargs.setdefault(&#34;fast_cli&#34;, True)
+        kwargs.setdefault(&#34;_legacy_mode&#34;, False)
+        return super().__init__(*args, **kwargs)
+
     def establish_connection(self):
         &#34;&#34;&#34;Establish SSH connection to the network device&#34;&#34;&#34;
         super().establish_connection(width=511, height=511)
 
     def session_preparation(self):
         &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-        self._test_channel_read()
-        self.set_base_prompt()
-        self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
+        # IOS-XR has an issue where it echoes the command even though it hasn&#39;t returned the prompt
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        cmd = &#34;terminal width 511&#34;
+        self.set_terminal_width(command=cmd, pattern=cmd)
         self.disable_paging()
-        # Clear the read buffer
-        time.sleep(0.3 * self.global_delay_factor)
-        self.clear_buffer()
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        self.set_base_prompt()
 
     def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
         &#34;&#34;&#34;IOS-XR requires you not exit from configuration mode.&#34;&#34;&#34;
@@ -145,17 +150,21 @@ class CiscoXrBase(CiscoBaseConnection):
         output = output.replace(&#34;(admin)&#34;, &#34;&#34;)
         return check_string in output
 
-    def exit_config_mode(self, exit_config=&#34;end&#34;):
+    def exit_config_mode(self, exit_config=&#34;end&#34;, pattern=&#34;&#34;):
         &#34;&#34;&#34;Exit configuration mode.&#34;&#34;&#34;
         output = &#34;&#34;
         if self.check_config_mode():
-            output = self.send_command_timing(
-                exit_config, strip_prompt=False, strip_command=False
-            )
-            if &#34;Uncommitted changes found&#34; in output:
-                output += self.send_command_timing(
-                    &#34;no&#34;, strip_prompt=False, strip_command=False
+            self.write_channel(self.normalize_cmd(exit_config))
+            # Make sure you read until you detect the command echo (avoid getting out of sync)
+            if self.global_cmd_verify is not False:
+                output += self.read_until_pattern(
+                    pattern=re.escape(exit_config.strip())
                 )
+            if &#34;Uncommitted changes found&#34; in output:
+                self.write_channel(self.normalize_cmd(&#34;no\n&#34;))
+                output += self.read_until_pattern(pattern=r&#34;[&gt;#]&#34;)
+            if not re.search(pattern, output, flags=re.M):
+                output += self.read_until_pattern(pattern=pattern)
             if self.check_config_mode():
                 raise ValueError(&#34;Failed to exit configuration mode&#34;)
         return output
@@ -229,7 +238,7 @@ class CiscoXrFileTransfer(CiscoFileTransfer):
 <dl>
 <dt id="netmiko.cisco.cisco_xr.CiscoXrBase"><code class="flex name class">
 <span>class <span class="ident">CiscoXrBase</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Base Class for cisco-like behavior.</p>
@@ -366,19 +375,25 @@ class CiscoXrFileTransfer(CiscoFileTransfer):
 <details class="source">
 <summary>Source code</summary>
 <pre><code class="python">class CiscoXrBase(CiscoBaseConnection):
+    def __init__(self, *args, **kwargs):
+        # Cisco NX-OS defaults to fast_cli=True and legacy_mode=False
+        kwargs.setdefault(&#34;fast_cli&#34;, True)
+        kwargs.setdefault(&#34;_legacy_mode&#34;, False)
+        return super().__init__(*args, **kwargs)
+
     def establish_connection(self):
         &#34;&#34;&#34;Establish SSH connection to the network device&#34;&#34;&#34;
         super().establish_connection(width=511, height=511)
 
     def session_preparation(self):
         &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-        self._test_channel_read()
-        self.set_base_prompt()
-        self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
+        # IOS-XR has an issue where it echoes the command even though it hasn&#39;t returned the prompt
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        cmd = &#34;terminal width 511&#34;
+        self.set_terminal_width(command=cmd, pattern=cmd)
         self.disable_paging()
-        # Clear the read buffer
-        time.sleep(0.3 * self.global_delay_factor)
-        self.clear_buffer()
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        self.set_base_prompt()
 
     def send_config_set(self, config_commands=None, exit_config_mode=False, **kwargs):
         &#34;&#34;&#34;IOS-XR requires you not exit from configuration mode.&#34;&#34;&#34;
@@ -483,17 +498,21 @@ class CiscoXrFileTransfer(CiscoFileTransfer):
         output = output.replace(&#34;(admin)&#34;, &#34;&#34;)
         return check_string in output
 
-    def exit_config_mode(self, exit_config=&#34;end&#34;):
+    def exit_config_mode(self, exit_config=&#34;end&#34;, pattern=&#34;&#34;):
         &#34;&#34;&#34;Exit configuration mode.&#34;&#34;&#34;
         output = &#34;&#34;
         if self.check_config_mode():
-            output = self.send_command_timing(
-                exit_config, strip_prompt=False, strip_command=False
-            )
-            if &#34;Uncommitted changes found&#34; in output:
-                output += self.send_command_timing(
-                    &#34;no&#34;, strip_prompt=False, strip_command=False
+            self.write_channel(self.normalize_cmd(exit_config))
+            # Make sure you read until you detect the command echo (avoid getting out of sync)
+            if self.global_cmd_verify is not False:
+                output += self.read_until_pattern(
+                    pattern=re.escape(exit_config.strip())
                 )
+            if &#34;Uncommitted changes found&#34; in output:
+                self.write_channel(self.normalize_cmd(&#34;no\n&#34;))
+                output += self.read_until_pattern(pattern=r&#34;[&gt;#]&#34;)
+            if not re.search(pattern, output, flags=re.M):
+                output += self.read_until_pattern(pattern=pattern)
             if self.check_config_mode():
                 raise ValueError(&#34;Failed to exit configuration mode&#34;)
         return output
@@ -666,23 +685,27 @@ an exception to be generated.</p></section>
 </details>
 </dd>
 <dt id="netmiko.cisco.cisco_xr.CiscoXrBase.exit_config_mode"><code class="name flex">
-<span>def <span class="ident">exit_config_mode</span></span>(<span>self, exit_config='end')</span>
+<span>def <span class="ident">exit_config_mode</span></span>(<span>self, exit_config='end', pattern='')</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Exit configuration mode.</p></section>
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">def exit_config_mode(self, exit_config=&#34;end&#34;):
+<pre><code class="python">def exit_config_mode(self, exit_config=&#34;end&#34;, pattern=&#34;&#34;):
     &#34;&#34;&#34;Exit configuration mode.&#34;&#34;&#34;
     output = &#34;&#34;
     if self.check_config_mode():
-        output = self.send_command_timing(
-            exit_config, strip_prompt=False, strip_command=False
-        )
-        if &#34;Uncommitted changes found&#34; in output:
-            output += self.send_command_timing(
-                &#34;no&#34;, strip_prompt=False, strip_command=False
+        self.write_channel(self.normalize_cmd(exit_config))
+        # Make sure you read until you detect the command echo (avoid getting out of sync)
+        if self.global_cmd_verify is not False:
+            output += self.read_until_pattern(
+                pattern=re.escape(exit_config.strip())
             )
+        if &#34;Uncommitted changes found&#34; in output:
+            self.write_channel(self.normalize_cmd(&#34;no\n&#34;))
+            output += self.read_until_pattern(pattern=r&#34;[&gt;#]&#34;)
+        if not re.search(pattern, output, flags=re.M):
+            output += self.read_until_pattern(pattern=pattern)
         if self.check_config_mode():
             raise ValueError(&#34;Failed to exit configuration mode&#34;)
     return output</code></pre>
@@ -723,13 +746,13 @@ an exception to be generated.</p></section>
 <summary>Source code</summary>
 <pre><code class="python">def session_preparation(self):
     &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-    self._test_channel_read()
-    self.set_base_prompt()
-    self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
+    # IOS-XR has an issue where it echoes the command even though it hasn&#39;t returned the prompt
+    self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+    cmd = &#34;terminal width 511&#34;
+    self.set_terminal_width(command=cmd, pattern=cmd)
     self.disable_paging()
-    # Clear the read buffer
-    time.sleep(0.3 * self.global_delay_factor)
-    self.clear_buffer()</code></pre>
+    self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+    self.set_base_prompt()</code></pre>
 </details>
 </dd>
 </dl>
@@ -907,7 +930,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section>
 </dd>
 <dt id="netmiko.cisco.cisco_xr.CiscoXrSSH"><code class="flex name class">
 <span>class <span class="ident">CiscoXrSSH</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Cisco XR SSH driver.</p>
@@ -1104,7 +1127,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section>
 </dd>
 <dt id="netmiko.cisco.cisco_xr.CiscoXrTelnet"><code class="flex name class">
 <span>class <span class="ident">CiscoXrTelnet</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Cisco XR Telnet driver.</p>
diff --git a/docs/netmiko/cisco/index.html b/docs/netmiko/cisco/index.html
index 8f748537dacf6827c080afff7d41e3d408ec40e0..b15d31ee8af157a7a3800f64decb88d0159042a8 100644
--- a/docs/netmiko/cisco/index.html
+++ b/docs/netmiko/cisco/index.html
@@ -31,6 +31,7 @@
 from netmiko.cisco.cisco_ios import CiscoIosFileTransfer
 from netmiko.cisco.cisco_ios import InLineTransfer
 from netmiko.cisco.cisco_asa_ssh import CiscoAsaSSH, CiscoAsaFileTransfer
+from netmiko.cisco.cisco_ftd_ssh import CiscoFtdSSH
 from netmiko.cisco.cisco_nxos_ssh import CiscoNxosSSH, CiscoNxosFileTransfer
 from netmiko.cisco.cisco_xr import CiscoXrSSH, CiscoXrTelnet, CiscoXrFileTransfer
 from netmiko.cisco.cisco_wlc_ssh import CiscoWlcSSH
@@ -41,6 +42,7 @@ __all__ = [
     &#34;CiscoIosSSH&#34;,
     &#34;CiscoIosTelnet&#34;,
     &#34;CiscoAsaSSH&#34;,
+    &#34;CiscoFtdSSH&#34;,
     &#34;CiscoNxosSSH&#34;,
     &#34;CiscoXrSSH&#34;,
     &#34;CiscoXrTelnet&#34;,
@@ -64,6 +66,10 @@ __all__ = [
 <dd>
 <section class="desc"><p>Subclass specific to Cisco ASA.</p></section>
 </dd>
+<dt><code class="name"><a title="netmiko.cisco.cisco_ftd_ssh" href="cisco_ftd_ssh.html">netmiko.cisco.cisco_ftd_ssh</a></code></dt>
+<dd>
+<section class="desc"><p>Subclass specific to Cisco FTD.</p></section>
+</dd>
 <dt><code class="name"><a title="netmiko.cisco.cisco_ios" href="cisco_ios.html">netmiko.cisco.cisco_ios</a></code></dt>
 <dd>
 <section class="desc"></section>
@@ -635,6 +641,281 @@ happens the trailing '(config*' needs stripped off.</p></section>
 </li>
 </ul>
 </dd>
+<dt id="netmiko.cisco.CiscoFtdSSH"><code class="flex name class">
+<span>class <span class="ident">CiscoFtdSSH</span></span>
+<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Subclass specific to Cisco FTD.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class CiscoFtdSSH(CiscoSSHConnection):
+    &#34;&#34;&#34;Subclass specific to Cisco FTD.&#34;&#34;&#34;
+
+    def session_preparation(self):
+        &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
+        self._test_channel_read()
+        self.set_base_prompt()
+
+    def send_config_set(self, *args, **kwargs):
+        &#34;&#34;&#34;Canot change config on FTD via ssh&#34;&#34;&#34;
+        raise NotImplementedError
+
+    def enable(self, *args, **kwargs):
+        &#34;&#34;&#34;No enable mode on firepower ssh&#34;&#34;&#34;
+        return &#34;&#34;
+
+    def config_mode(self, *args, **kwargs):
+        &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+        return &#34;&#34;
+
+    def check_config_mode(self, *args, **kwargs):
+        &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+        return False</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Methods</h3>
+<dl>
+<dt id="netmiko.cisco.CiscoFtdSSH.check_config_mode"><code class="name flex">
+<span>def <span class="ident">check_config_mode</span></span>(<span>self, *args, **kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>No config mode on firepower ssh</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def check_config_mode(self, *args, **kwargs):
+    &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+    return False</code></pre>
+</details>
+</dd>
+<dt id="netmiko.cisco.CiscoFtdSSH.config_mode"><code class="name flex">
+<span>def <span class="ident">config_mode</span></span>(<span>self, *args, **kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>No config mode on firepower ssh</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def config_mode(self, *args, **kwargs):
+    &#34;&#34;&#34;No config mode on firepower ssh&#34;&#34;&#34;
+    return &#34;&#34;</code></pre>
+</details>
+</dd>
+<dt id="netmiko.cisco.CiscoFtdSSH.enable"><code class="name flex">
+<span>def <span class="ident">enable</span></span>(<span>self, *args, **kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>No enable mode on firepower ssh</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def enable(self, *args, **kwargs):
+    &#34;&#34;&#34;No enable mode on firepower ssh&#34;&#34;&#34;
+    return &#34;&#34;</code></pre>
+</details>
+</dd>
+<dt id="netmiko.cisco.CiscoFtdSSH.send_config_set"><code class="name flex">
+<span>def <span class="ident">send_config_set</span></span>(<span>self, *args, **kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Canot change config on FTD via ssh</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def send_config_set(self, *args, **kwargs):
+    &#34;&#34;&#34;Canot change config on FTD via ssh&#34;&#34;&#34;
+    raise NotImplementedError</code></pre>
+</details>
+</dd>
+<dt id="netmiko.cisco.CiscoFtdSSH.session_preparation"><code class="name flex">
+<span>def <span class="ident">session_preparation</span></span>(<span>self)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Prepare the session after the connection has been established.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def session_preparation(self):
+    &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
+    self._test_channel_read()
+    self.set_base_prompt()</code></pre>
+</details>
+</dd>
+</dl>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_config_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_base_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_base_prompt">set_base_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
 <dt id="netmiko.cisco.CiscoIosBase"><code class="flex name class">
 <span>class <span class="ident">CiscoIosBase</span></span>
 <span>(</span><span>*args, **kwargs)</span>
@@ -1685,7 +1966,7 @@ def process_md5(md5_output, pattern=r&#34;= (.*)&#34;):
 </dd>
 <dt id="netmiko.cisco.CiscoNxosSSH"><code class="flex name class">
 <span>class <span class="ident">CiscoNxosSSH</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Base Class for cisco-like behavior.</p>
@@ -1822,16 +2103,22 @@ def process_md5(md5_output, pattern=r&#34;= (.*)&#34;):
 <details class="source">
 <summary>Source code</summary>
 <pre><code class="python">class CiscoNxosSSH(CiscoSSHConnection):
+    def __init__(self, *args, **kwargs):
+        # Cisco NX-OS defaults to fast_cli=True and legacy_mode=False
+        kwargs.setdefault(&#34;fast_cli&#34;, True)
+        kwargs.setdefault(&#34;_legacy_mode&#34;, False)
+        return super().__init__(*args, **kwargs)
+
     def session_preparation(self):
         &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
         self.ansi_escape_codes = True
-        self.set_base_prompt()
-        self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
+        # NX-OS has an issue where it echoes the command even though it hasn&#39;t returned the prompt
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        self.set_terminal_width(
+            command=&#34;terminal width 511&#34;, pattern=r&#34;terminal width 511&#34;
+        )
         self.disable_paging()
-        # Clear the read buffer
-        time.sleep(0.3 * self.global_delay_factor)
-        self.clear_buffer()
+        self.set_base_prompt()
 
     def normalize_linefeeds(self, a_string):
         &#34;&#34;&#34;Convert &#39;\r\n&#39; or &#39;\r\r\n&#39; to &#39;\n, and remove extra &#39;\r&#39;s in the text.&#34;&#34;&#34;
@@ -1890,14 +2177,14 @@ def process_md5(md5_output, pattern=r&#34;= (.*)&#34;):
 <summary>Source code</summary>
 <pre><code class="python">def session_preparation(self):
     &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
-    self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
     self.ansi_escape_codes = True
-    self.set_base_prompt()
-    self.set_terminal_width(command=&#34;terminal width 511&#34;, pattern=&#34;terminal&#34;)
+    # NX-OS has an issue where it echoes the command even though it hasn&#39;t returned the prompt
+    self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+    self.set_terminal_width(
+        command=&#34;terminal width 511&#34;, pattern=r&#34;terminal width 511&#34;
+    )
     self.disable_paging()
-    # Clear the read buffer
-    time.sleep(0.3 * self.global_delay_factor)
-    self.clear_buffer()</code></pre>
+    self.set_base_prompt()</code></pre>
 </details>
 </dd>
 </dl>
@@ -3329,7 +3616,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section>
 </dd>
 <dt id="netmiko.cisco.CiscoXrSSH"><code class="flex name class">
 <span>class <span class="ident">CiscoXrSSH</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Cisco XR SSH driver.</p>
@@ -3526,7 +3813,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section>
 </dd>
 <dt id="netmiko.cisco.CiscoXrTelnet"><code class="flex name class">
 <span>class <span class="ident">CiscoXrTelnet</span></span>
-<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+<span>(</span><span>*args, **kwargs)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Cisco XR Telnet driver.</p>
@@ -3991,6 +4278,7 @@ c84843f0030efd44b01343fdb8c2e801</p></section>
 <li><h3><a href="#header-submodules">Sub-modules</a></h3>
 <ul>
 <li><code><a title="netmiko.cisco.cisco_asa_ssh" href="cisco_asa_ssh.html">netmiko.cisco.cisco_asa_ssh</a></code></li>
+<li><code><a title="netmiko.cisco.cisco_ftd_ssh" href="cisco_ftd_ssh.html">netmiko.cisco.cisco_ftd_ssh</a></code></li>
 <li><code><a title="netmiko.cisco.cisco_ios" href="cisco_ios.html">netmiko.cisco.cisco_ios</a></code></li>
 <li><code><a title="netmiko.cisco.cisco_nxos_ssh" href="cisco_nxos_ssh.html">netmiko.cisco.cisco_nxos_ssh</a></code></li>
 <li><code><a title="netmiko.cisco.cisco_s300" href="cisco_s300.html">netmiko.cisco.cisco_s300</a></code></li>
@@ -4017,6 +4305,16 @@ c84843f0030efd44b01343fdb8c2e801</p></section>
 </ul>
 </li>
 <li>
+<h4><code><a title="netmiko.cisco.CiscoFtdSSH" href="#netmiko.cisco.CiscoFtdSSH">CiscoFtdSSH</a></code></h4>
+<ul class="">
+<li><code><a title="netmiko.cisco.CiscoFtdSSH.check_config_mode" href="#netmiko.cisco.CiscoFtdSSH.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.cisco.CiscoFtdSSH.config_mode" href="#netmiko.cisco.CiscoFtdSSH.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.cisco.CiscoFtdSSH.enable" href="#netmiko.cisco.CiscoFtdSSH.enable">enable</a></code></li>
+<li><code><a title="netmiko.cisco.CiscoFtdSSH.send_config_set" href="#netmiko.cisco.CiscoFtdSSH.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.cisco.CiscoFtdSSH.session_preparation" href="#netmiko.cisco.CiscoFtdSSH.session_preparation">session_preparation</a></code></li>
+</ul>
+</li>
+<li>
 <h4><code><a title="netmiko.cisco.CiscoIosBase" href="#netmiko.cisco.CiscoIosBase">CiscoIosBase</a></code></h4>
 <ul class="">
 <li><code><a title="netmiko.cisco.CiscoIosBase.save_config" href="#netmiko.cisco.CiscoIosBase.save_config">save_config</a></code></li>
diff --git a/docs/netmiko/cisco_base_connection.html b/docs/netmiko/cisco_base_connection.html
index 610fb453665fac4ede023998863a61c207e4c218..579cd59b85d1b3275516e564b832a20591260314 100644
--- a/docs/netmiko/cisco_base_connection.html
+++ b/docs/netmiko/cisco_base_connection.html
@@ -54,7 +54,7 @@ class CiscoBaseConnection(BaseConnection):
         &#34;&#34;&#34;
         return super().check_config_mode(check_string=check_string, pattern=pattern)
 
-    def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;):
+    def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;, re_flags=0):
         &#34;&#34;&#34;
         Enter into configuration mode on remote device.
 
@@ -62,7 +62,9 @@ class CiscoBaseConnection(BaseConnection):
         &#34;&#34;&#34;
         if not pattern:
             pattern = re.escape(self.base_prompt[:16])
-        return super().config_mode(config_command=config_command, pattern=pattern)
+        return super().config_mode(
+            config_command=config_command, pattern=pattern, re_flags=re_flags
+        )
 
     def exit_config_mode(self, exit_config=&#34;end&#34;, pattern=&#34;#&#34;):
         &#34;&#34;&#34;Exit from configuration mode.&#34;&#34;&#34;
@@ -436,7 +438,7 @@ class CiscoFileTransfer(BaseFileTransfer):
         &#34;&#34;&#34;
         return super().check_config_mode(check_string=check_string, pattern=pattern)
 
-    def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;):
+    def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;, re_flags=0):
         &#34;&#34;&#34;
         Enter into configuration mode on remote device.
 
@@ -444,7 +446,9 @@ class CiscoFileTransfer(BaseFileTransfer):
         &#34;&#34;&#34;
         if not pattern:
             pattern = re.escape(self.base_prompt[:16])
-        return super().config_mode(config_command=config_command, pattern=pattern)
+        return super().config_mode(
+            config_command=config_command, pattern=pattern, re_flags=re_flags
+        )
 
     def exit_config_mode(self, exit_config=&#34;end&#34;, pattern=&#34;#&#34;):
         &#34;&#34;&#34;Exit from configuration mode.&#34;&#34;&#34;
@@ -712,14 +716,14 @@ class CiscoFileTransfer(BaseFileTransfer):
 </details>
 </dd>
 <dt id="netmiko.cisco_base_connection.CiscoBaseConnection.config_mode"><code class="name flex">
-<span>def <span class="ident">config_mode</span></span>(<span>self, config_command='configure terminal', pattern='')</span>
+<span>def <span class="ident">config_mode</span></span>(<span>self, config_command='configure terminal', pattern='', re_flags=0)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter into configuration mode on remote device.</p>
 <p>Cisco IOS devices abbreviate the prompt at 20 chars in config mode</p></section>
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;):
+<pre><code class="python">def config_mode(self, config_command=&#34;configure terminal&#34;, pattern=&#34;&#34;, re_flags=0):
     &#34;&#34;&#34;
     Enter into configuration mode on remote device.
 
@@ -727,11 +731,13 @@ class CiscoFileTransfer(BaseFileTransfer):
     &#34;&#34;&#34;
     if not pattern:
         pattern = re.escape(self.base_prompt[:16])
-    return super().config_mode(config_command=config_command, pattern=pattern)</code></pre>
+    return super().config_mode(
+        config_command=config_command, pattern=pattern, re_flags=re_flags
+    )</code></pre>
 </details>
 </dd>
 <dt id="netmiko.cisco_base_connection.CiscoBaseConnection.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='ssword', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter enable mode.</p></section>
@@ -1189,6 +1195,7 @@ class CiscoFileTransfer(BaseFileTransfer):
 <li><a title="netmiko.broadcom.broadcom_icos_ssh.BroadcomIcosSSH" href="broadcom/broadcom_icos_ssh.html#netmiko.broadcom.broadcom_icos_ssh.BroadcomIcosSSH">BroadcomIcosSSH</a></li>
 <li><a title="netmiko.calix.calix_b6.CalixB6Base" href="calix/calix_b6.html#netmiko.calix.calix_b6.CalixB6Base">CalixB6Base</a></li>
 <li><a title="netmiko.cisco.cisco_asa_ssh.CiscoAsaSSH" href="cisco/cisco_asa_ssh.html#netmiko.cisco.cisco_asa_ssh.CiscoAsaSSH">CiscoAsaSSH</a></li>
+<li><a title="netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH" href="cisco/cisco_ftd_ssh.html#netmiko.cisco.cisco_ftd_ssh.CiscoFtdSSH">CiscoFtdSSH</a></li>
 <li><a title="netmiko.cisco.cisco_nxos_ssh.CiscoNxosSSH" href="cisco/cisco_nxos_ssh.html#netmiko.cisco.cisco_nxos_ssh.CiscoNxosSSH">CiscoNxosSSH</a></li>
 <li><a title="netmiko.cisco.cisco_s300.CiscoS300SSH" href="cisco/cisco_s300.html#netmiko.cisco.cisco_s300.CiscoS300SSH">CiscoS300SSH</a></li>
 <li><a title="netmiko.cisco.cisco_tp_tcce.CiscoTpTcCeSSH" href="cisco/cisco_tp_tcce.html#netmiko.cisco.cisco_tp_tcce.CiscoTpTcCeSSH">CiscoTpTcCeSSH</a></li>
@@ -1220,6 +1227,7 @@ class CiscoFileTransfer(BaseFileTransfer):
 <li><a title="netmiko.quanta.quanta_mesh_ssh.QuantaMeshSSH" href="quanta/quanta_mesh_ssh.html#netmiko.quanta.quanta_mesh_ssh.QuantaMeshSSH">QuantaMeshSSH</a></li>
 <li><a title="netmiko.ruckus.ruckus_fastiron.RuckusFastironBase" href="ruckus/ruckus_fastiron.html#netmiko.ruckus.ruckus_fastiron.RuckusFastironBase">RuckusFastironBase</a></li>
 <li><a title="netmiko.sophos.sophos_sfos_ssh.SophosSfosSSH" href="sophos/sophos_sfos_ssh.html#netmiko.sophos.sophos_sfos_ssh.SophosSfosSSH">SophosSfosSSH</a></li>
+<li><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="tplink/tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></li>
 <li><a title="netmiko.ubiquiti.edge_ssh.UbiquitiEdgeSSH" href="ubiquiti/edge_ssh.html#netmiko.ubiquiti.edge_ssh.UbiquitiEdgeSSH">UbiquitiEdgeSSH</a></li>
 <li><a title="netmiko.vyos.vyos_ssh.VyOSSSH" href="vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH">VyOSSSH</a></li>
 </ul>
diff --git a/docs/netmiko/fortinet/fortinet_ssh.html b/docs/netmiko/fortinet/fortinet_ssh.html
index ad4e086c282b0880ca9e4a1ffc33b86d3f7348ce..98dcd20f460365cc15186746609dcbf6c2d6f190 100644
--- a/docs/netmiko/fortinet/fortinet_ssh.html
+++ b/docs/netmiko/fortinet/fortinet_ssh.html
@@ -70,7 +70,7 @@ class FortinetSSH(CiscoSSHConnection):
         self.vdoms = False
         self._output_mode = &#34;more&#34;
 
-        if &#34;Virtual domain configuration: enable&#34; in output:
+        if re.search(r&#34;Virtual domain configuration: (multiple|enable)&#34;, output):
             self.vdoms = True
             vdom_additional_command = &#34;config global&#34;
             output = self.send_command_timing(vdom_additional_command, delay_factor=2)
@@ -324,7 +324,7 @@ class FortinetSSH(CiscoSSHConnection):
         self.vdoms = False
         self._output_mode = &#34;more&#34;
 
-        if &#34;Virtual domain configuration: enable&#34; in output:
+        if re.search(r&#34;Virtual domain configuration: (multiple|enable)&#34;, output):
             self.vdoms = True
             vdom_additional_command = &#34;config global&#34;
             output = self.send_command_timing(vdom_additional_command, delay_factor=2)
@@ -444,7 +444,7 @@ class FortinetSSH(CiscoSSHConnection):
     self.vdoms = False
     self._output_mode = &#34;more&#34;
 
-    if &#34;Virtual domain configuration: enable&#34; in output:
+    if re.search(r&#34;Virtual domain configuration: (multiple|enable)&#34;, output):
         self.vdoms = True
         vdom_additional_command = &#34;config global&#34;
         output = self.send_command_timing(vdom_additional_command, delay_factor=2)
diff --git a/docs/netmiko/fortinet/index.html b/docs/netmiko/fortinet/index.html
index 38004bb03fe67daeb719e4055dacb5efeb5bda23..ce460865af7886bc86294a05d49e96a6d22c63fc 100644
--- a/docs/netmiko/fortinet/index.html
+++ b/docs/netmiko/fortinet/index.html
@@ -223,7 +223,7 @@ __all__ = [&#34;FortinetSSH&#34;]</code></pre>
         self.vdoms = False
         self._output_mode = &#34;more&#34;
 
-        if &#34;Virtual domain configuration: enable&#34; in output:
+        if re.search(r&#34;Virtual domain configuration: (multiple|enable)&#34;, output):
             self.vdoms = True
             vdom_additional_command = &#34;config global&#34;
             output = self.send_command_timing(vdom_additional_command, delay_factor=2)
@@ -343,7 +343,7 @@ __all__ = [&#34;FortinetSSH&#34;]</code></pre>
     self.vdoms = False
     self._output_mode = &#34;more&#34;
 
-    if &#34;Virtual domain configuration: enable&#34; in output:
+    if re.search(r&#34;Virtual domain configuration: (multiple|enable)&#34;, output):
         self.vdoms = True
         vdom_additional_command = &#34;config global&#34;
         output = self.send_command_timing(vdom_additional_command, delay_factor=2)
diff --git a/docs/netmiko/hp/hp_procurve.html b/docs/netmiko/hp/hp_procurve.html
index e2a9237eb6a7a524ec8fac4a24a83fdfd5708355..a968592bddc623bc9966c39b8f16660c7f307e83 100644
--- a/docs/netmiko/hp/hp_procurve.html
+++ b/docs/netmiko/hp/hp_procurve.html
@@ -483,7 +483,7 @@ class HPProcurveTelnet(HPProcurveBase):
 <h3>Methods</h3>
 <dl>
 <dt id="netmiko.hp.hp_procurve.HPProcurveBase.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='password', re_flags=<RegexFlag.IGNORECASE: 2>, default_username='manager')</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='password', re_flags=re.IGNORECASE, default_username='manager')</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter enable mode</p></section>
diff --git a/docs/netmiko/huawei/huawei.html b/docs/netmiko/huawei/huawei.html
index 9944c49774df65e7e573635602b063f676e465a9..be79bceae30273e9392ffafe3fda68dcda54e561 100644
--- a/docs/netmiko/huawei/huawei.html
+++ b/docs/netmiko/huawei/huawei.html
@@ -52,9 +52,6 @@ class HuaweiBase(CiscoBaseConnection):
         pattern = rf&#34; {code_cursor_left}&#34;
         output = re.sub(pattern, &#34;&#34;, output)
 
-        log.debug(&#34;Stripping ANSI escape codes&#34;)
-        log.debug(f&#34;new_output = {output}&#34;)
-        log.debug(f&#34;repr = {repr(output)}&#34;)
         return super().strip_ansi_escape_codes(output)
 
     def config_mode(self, config_command=&#34;system-view&#34;):
@@ -431,9 +428,6 @@ class HuaweiVrpv8SSH(HuaweiSSH):
         pattern = rf&#34; {code_cursor_left}&#34;
         output = re.sub(pattern, &#34;&#34;, output)
 
-        log.debug(&#34;Stripping ANSI escape codes&#34;)
-        log.debug(f&#34;new_output = {output}&#34;)
-        log.debug(f&#34;repr = {repr(output)}&#34;)
         return super().strip_ansi_escape_codes(output)
 
     def config_mode(self, config_command=&#34;system-view&#34;):
@@ -697,9 +691,6 @@ to move the cursor to the left one.</p>
     pattern = rf&#34; {code_cursor_left}&#34;
     output = re.sub(pattern, &#34;&#34;, output)
 
-    log.debug(&#34;Stripping ANSI escape codes&#34;)
-    log.debug(f&#34;new_output = {output}&#34;)
-    log.debug(f&#34;repr = {repr(output)}&#34;)
     return super().strip_ansi_escape_codes(output)</code></pre>
 </details>
 </dd>
diff --git a/docs/netmiko/index.html b/docs/netmiko/index.html
index 21bc651159bd1444075256c288a05c109580c2c2..3a390eb3361ff56e19c88d94dfe09187bee6dd76 100644
--- a/docs/netmiko/index.html
+++ b/docs/netmiko/index.html
@@ -47,7 +47,7 @@ from netmiko.scp_functions import file_transfer, progress_bar
 # Alternate naming
 Netmiko = ConnectHandler
 
-__version__ = &#34;3.3.0&#34;
+__version__ = &#34;3.3.2&#34;
 __all__ = (
     &#34;ConnectHandler&#34;,
     &#34;ssh_dispatcher&#34;,
@@ -304,6 +304,10 @@ a new SSH connection with a remote host. This …</p></section>
 <dd>
 <section class="desc"></section>
 </dd>
+<dt><code class="name"><a title="netmiko.tplink" href="tplink/index.html">netmiko.tplink</a></code></dt>
+<dd>
+<section class="desc"></section>
+</dd>
 <dt><code class="name"><a title="netmiko.ubiquiti" href="ubiquiti/index.html">netmiko.ubiquiti</a></code></dt>
 <dd>
 <section class="desc"></section>
@@ -528,7 +532,8 @@ a new SSH connection with a remote host. This …</p></section>
 <summary>Source code</summary>
 <pre><code class="python">def progress_bar(filename, size, sent, peername=None):
     max_width = 50
-    filename = filename.decode()
+    if isinstance(filename, bytes):
+        filename = filename.decode()
     clear_screen = chr(27) + &#34;[2J&#34;
     terminating_char = &#34;|&#34;
 
@@ -1672,6 +1677,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 print(&#34;Interactive SSH session established&#34;)
         return &#34;&#34;
 
+    # @m_exec_time
     def _test_channel_read(self, count=40, pattern=&#34;&#34;):
         &#34;&#34;&#34;Try to read the channel (generally post login) verify you receive data back.
 
@@ -1703,6 +1709,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 break
             else:
                 self.write_channel(self.RETURN)
+
             main_delay = _increment_delay(main_delay)
             time.sleep(main_delay)
             i += 1
@@ -1737,7 +1744,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
         :type delay_factor: int
         &#34;&#34;&#34;
         if self.fast_cli:
-            if delay_factor &lt;= self.global_delay_factor:
+            if delay_factor and delay_factor &lt;= self.global_delay_factor:
                 return delay_factor
             else:
                 return self.global_delay_factor
@@ -1806,6 +1813,10 @@ Device settings: {self.device_type} {self.host}:{self.port}
             output = self.read_until_prompt()
         return output
 
+    # Retry by sleeping .33 and then double sleep until 5 attempts (.33, .66, 1.32, etc)
+    @retry(
+        wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5)
+    )
     def set_base_prompt(
         self, pri_prompt_terminator=&#34;#&#34;, alt_prompt_terminator=&#34;&gt;&#34;, delay_factor=1
     ):
@@ -1951,13 +1962,19 @@ Device settings: {self.device_type} {self.host}:{self.port}
         :param cmd_echo: Deprecated (use cmd_verify instead)
         :type cmd_echo: bool
         &#34;&#34;&#34;
-        # For compatibility remove cmd_echo in Netmiko 4.x.x
+
+        # For compatibility; remove cmd_echo in Netmiko 4.x.x
         if cmd_echo is not None:
             cmd_verify = cmd_echo
 
         output = &#34;&#34;
+
         delay_factor = self.select_delay_factor(delay_factor)
-        self.clear_buffer()
+        # Cleanup in future versions of Netmiko
+        if delay_factor &lt; 1:
+            if not self._legacy_mode and self.fast_cli:
+                delay_factor = 1
+
         if normalize:
             command_string = self.normalize_cmd(command_string)
 
@@ -1992,7 +2009,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             strip_prompt=strip_prompt,
         )
 
-        # If both TextFSM and Genie are set, try TextFSM then Genie
+        # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
         if use_textfsm:
             structured_output = get_structured_data(
                 output,
@@ -2003,6 +2020,11 @@ Device settings: {self.device_type} {self.host}:{self.port}
             # If we have structured data; return it.
             if not isinstance(structured_output, str):
                 return structured_output
+        if use_ttp:
+            structured_output = get_structured_data_ttp(output, template=ttp_template)
+            # If we have structured data; return it.
+            if not isinstance(structured_output, str):
+                return structured_output
         if use_genie:
             structured_output = get_structured_data_genie(
                 output, platform=self.device_type, command=command_string.strip()
@@ -2067,6 +2089,8 @@ Device settings: {self.device_type} {self.host}:{self.port}
         normalize=True,
         use_textfsm=False,
         textfsm_template=None,
+        use_ttp=False,
+        ttp_template=None,
         use_genie=False,
         cmd_verify=True,
     ):
@@ -2192,7 +2216,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             new_data = self.read_channel()
         else:  # nobreak
             raise IOError(
-                &#34;Search pattern never detected in send_command_expect: {}&#34;.format(
+                &#34;Search pattern never detected in send_command: {}&#34;.format(
                     search_pattern
                 )
             )
@@ -2204,7 +2228,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             strip_prompt=strip_prompt,
         )
 
-        # If both TextFSM and Genie are set, try TextFSM then Genie
+        # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
         if use_textfsm:
             structured_output = get_structured_data(
                 output,
@@ -2215,6 +2239,11 @@ Device settings: {self.device_type} {self.host}:{self.port}
             # If we have structured data; return it.
             if not isinstance(structured_output, str):
                 return structured_output
+        if use_ttp:
+            structured_output = get_structured_data_ttp(output, template=ttp_template)
+            # If we have structured data; return it.
+            if not isinstance(structured_output, str):
+                return structured_output
         if use_genie:
             structured_output = get_structured_data_genie(
                 output, platform=self.device_type, command=command_string.strip()
@@ -2371,7 +2400,7 @@ Device settings: {self.device_type} {self.host}:{self.port}
             output = self.read_until_pattern(pattern=pattern)
         return check_string in output
 
-    def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;):
+    def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;, re_flags=0):
         &#34;&#34;&#34;Enter into config_mode.
 
         :param config_command: Configuration command to send to the device
@@ -2379,6 +2408,9 @@ Device settings: {self.device_type} {self.host}:{self.port}
 
         :param pattern: Pattern to terminate reading of channel
         :type pattern: str
+
+        :param re_flags: Regular expression flags
+        :type re_flags: RegexFlag
         &#34;&#34;&#34;
         output = &#34;&#34;
         if not self.check_config_mode():
@@ -2388,8 +2420,8 @@ Device settings: {self.device_type} {self.host}:{self.port}
                 output += self.read_until_pattern(
                     pattern=re.escape(config_command.strip())
                 )
-            if not re.search(pattern, output, flags=re.M):
-                output += self.read_until_pattern(pattern=pattern)
+            if not re.search(pattern, output, flags=re_flags):
+                output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
             if not self.check_config_mode():
                 raise ValueError(&#34;Failed to enter configuration mode.&#34;)
         return output
@@ -2840,17 +2872,19 @@ def strip_backspaces(output):
 </details>
 </dd>
 <dt id="netmiko.BaseConnection.config_mode"><code class="name flex">
-<span>def <span class="ident">config_mode</span></span>(<span>self, config_command='', pattern='')</span>
+<span>def <span class="ident">config_mode</span></span>(<span>self, config_command='', pattern='', re_flags=0)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter into config_mode.</p>
 <p>:param config_command: Configuration command to send to the device
 :type config_command: str</p>
 <p>:param pattern: Pattern to terminate reading of channel
-:type pattern: str</p></section>
+:type pattern: str</p>
+<p>:param re_flags: Regular expression flags
+:type re_flags: RegexFlag</p></section>
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;):
+<pre><code class="python">def config_mode(self, config_command=&#34;&#34;, pattern=&#34;&#34;, re_flags=0):
     &#34;&#34;&#34;Enter into config_mode.
 
     :param config_command: Configuration command to send to the device
@@ -2858,6 +2892,9 @@ def strip_backspaces(output):
 
     :param pattern: Pattern to terminate reading of channel
     :type pattern: str
+
+    :param re_flags: Regular expression flags
+    :type re_flags: RegexFlag
     &#34;&#34;&#34;
     output = &#34;&#34;
     if not self.check_config_mode():
@@ -2867,8 +2904,8 @@ def strip_backspaces(output):
             output += self.read_until_pattern(
                 pattern=re.escape(config_command.strip())
             )
-        if not re.search(pattern, output, flags=re.M):
-            output += self.read_until_pattern(pattern=pattern)
+        if not re.search(pattern, output, flags=re_flags):
+            output += self.read_until_pattern(pattern=pattern, re_flags=re_flags)
         if not self.check_config_mode():
             raise ValueError(&#34;Failed to enter configuration mode.&#34;)
     return output</code></pre>
@@ -2940,7 +2977,7 @@ def strip_backspaces(output):
 </details>
 </dd>
 <dt id="netmiko.BaseConnection.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='', pattern='ssword', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter enable mode.</p>
@@ -3425,7 +3462,7 @@ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.</p>
     :type delay_factor: int
     &#34;&#34;&#34;
     if self.fast_cli:
-        if delay_factor &lt;= self.global_delay_factor:
+        if delay_factor and delay_factor &lt;= self.global_delay_factor:
             return delay_factor
         else:
             return self.global_delay_factor
@@ -3437,7 +3474,7 @@ In fast_cli choose the lesser of delay_factor of self.global_delay_factor.</p>
 </details>
 </dd>
 <dt id="netmiko.BaseConnection.send_command"><code class="name flex">
-<span>def <span class="ident">send_command</span></span>(<span>self, command_string, expect_string=None, delay_factor=1, max_loops=500, auto_find_prompt=True, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_genie=False, cmd_verify=True)</span>
+<span>def <span class="ident">send_command</span></span>(<span>self, command_string, expect_string=None, delay_factor=1, max_loops=500, auto_find_prompt=True, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_ttp=False, ttp_template=None, use_genie=False, cmd_verify=True)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Execute command_string on the SSH channel using a pattern-based mechanism. Generally
@@ -3464,6 +3501,11 @@ based upon self.timeout.
 :type normalize: bool</p>
 <p>:param textfsm_template: Name of template to parse output with; can be fully qualified
 path, relative path, or name of file in current directory. (default: None).</p>
+<p>:param use_ttp: Process command output through TTP template (default: False).
+:type use_ttp: bool</p>
+<p>:param ttp_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:type ttp_template: str</p>
 <p>:param use_genie: Process command output through PyATS/Genie parser (default: False).
 :type normalize: bool</p>
 <p>:param cmd_verify: Verify command echo before proceeding (default: True).
@@ -3483,6 +3525,8 @@ def send_command(
     normalize=True,
     use_textfsm=False,
     textfsm_template=None,
+    use_ttp=False,
+    ttp_template=None,
     use_genie=False,
     cmd_verify=True,
 ):
@@ -3520,6 +3564,13 @@ def send_command(
     :param textfsm_template: Name of template to parse output with; can be fully qualified
         path, relative path, or name of file in current directory. (default: None).
 
+    :param use_ttp: Process command output through TTP template (default: False).
+    :type use_ttp: bool
+
+    :param ttp_template: Name of template to parse output with; can be fully qualified
+        path, relative path, or name of file in current directory. (default: None).
+    :type ttp_template: str
+
     :param use_genie: Process command output through PyATS/Genie parser (default: False).
     :type normalize: bool
 
@@ -3601,7 +3652,7 @@ def send_command(
         new_data = self.read_channel()
     else:  # nobreak
         raise IOError(
-            &#34;Search pattern never detected in send_command_expect: {}&#34;.format(
+            &#34;Search pattern never detected in send_command: {}&#34;.format(
                 search_pattern
             )
         )
@@ -3613,7 +3664,7 @@ def send_command(
         strip_prompt=strip_prompt,
     )
 
-    # If both TextFSM and Genie are set, try TextFSM then Genie
+    # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
     if use_textfsm:
         structured_output = get_structured_data(
             output,
@@ -3624,6 +3675,11 @@ def send_command(
         # If we have structured data; return it.
         if not isinstance(structured_output, str):
             return structured_output
+    if use_ttp:
+        structured_output = get_structured_data_ttp(output, template=ttp_template)
+        # If we have structured data; return it.
+        if not isinstance(structured_output, str):
+            return structured_output
     if use_genie:
         structured_output = get_structured_data_genie(
             output, platform=self.device_type, command=command_string.strip()
@@ -3658,7 +3714,7 @@ def send_command(
 </details>
 </dd>
 <dt id="netmiko.BaseConnection.send_command_timing"><code class="name flex">
-<span>def <span class="ident">send_command_timing</span></span>(<span>self, command_string, delay_factor=1, max_loops=150, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_genie=False, cmd_verify=False, cmd_echo=None)</span>
+<span>def <span class="ident">send_command_timing</span></span>(<span>self, command_string, delay_factor=1, max_loops=150, strip_prompt=True, strip_command=True, normalize=True, use_textfsm=False, textfsm_template=None, use_ttp=False, ttp_template=None, use_genie=False, cmd_verify=False, cmd_echo=None)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Execute command_string on the SSH channel using a delay-based mechanism. Generally
@@ -3681,6 +3737,11 @@ based upon self.timeout.
 <p>:param textfsm_template: Name of template to parse output with; can be fully qualified
 path, relative path, or name of file in current directory. (default: None).
 :type textfsm_template: str</p>
+<p>:param use_ttp: Process command output through TTP template (default: False).
+:type use_ttp: bool</p>
+<p>:param ttp_template: Name of template to parse output with; can be fully qualified
+path, relative path, or name of file in current directory. (default: None).
+:type ttp_template: str</p>
 <p>:param use_genie: Process command output through PyATS/Genie parser (default: False).
 :type use_genie: bool</p>
 <p>:param cmd_verify: Verify command echo before proceeding (default: False).
@@ -3700,6 +3761,8 @@ def send_command_timing(
     normalize=True,
     use_textfsm=False,
     textfsm_template=None,
+    use_ttp=False,
+    ttp_template=None,
     use_genie=False,
     cmd_verify=False,
     cmd_echo=None,
@@ -3733,6 +3796,13 @@ def send_command_timing(
         path, relative path, or name of file in current directory. (default: None).
     :type textfsm_template: str
 
+    :param use_ttp: Process command output through TTP template (default: False).
+    :type use_ttp: bool
+
+    :param ttp_template: Name of template to parse output with; can be fully qualified
+        path, relative path, or name of file in current directory. (default: None).
+    :type ttp_template: str
+
     :param use_genie: Process command output through PyATS/Genie parser (default: False).
     :type use_genie: bool
 
@@ -3742,13 +3812,19 @@ def send_command_timing(
     :param cmd_echo: Deprecated (use cmd_verify instead)
     :type cmd_echo: bool
     &#34;&#34;&#34;
-    # For compatibility remove cmd_echo in Netmiko 4.x.x
+
+    # For compatibility; remove cmd_echo in Netmiko 4.x.x
     if cmd_echo is not None:
         cmd_verify = cmd_echo
 
     output = &#34;&#34;
+
     delay_factor = self.select_delay_factor(delay_factor)
-    self.clear_buffer()
+    # Cleanup in future versions of Netmiko
+    if delay_factor &lt; 1:
+        if not self._legacy_mode and self.fast_cli:
+            delay_factor = 1
+
     if normalize:
         command_string = self.normalize_cmd(command_string)
 
@@ -3783,7 +3859,7 @@ def send_command_timing(
         strip_prompt=strip_prompt,
     )
 
-    # If both TextFSM and Genie are set, try TextFSM then Genie
+    # If both TextFSM, TTP and Genie are set, try TextFSM then TTP then Genie
     if use_textfsm:
         structured_output = get_structured_data(
             output,
@@ -3794,6 +3870,11 @@ def send_command_timing(
         # If we have structured data; return it.
         if not isinstance(structured_output, str):
             return structured_output
+    if use_ttp:
+        structured_output = get_structured_data_ttp(output, template=ttp_template)
+        # If we have structured data; return it.
+        if not isinstance(structured_output, str):
+            return structured_output
     if use_genie:
         structured_output = get_structured_data_genie(
             output, platform=self.device_type, command=command_string.strip()
@@ -4052,7 +4133,10 @@ entering/exiting config mode.</p>
 :type delay_factor: int</p></section>
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">def set_base_prompt(
+<pre><code class="python">@retry(
+    wait=wait_exponential(multiplier=0.33, min=0, max=5), stop=stop_after_attempt(5)
+)
+def set_base_prompt(
     self, pri_prompt_terminator=&#34;#&#34;, alt_prompt_terminator=&#34;&gt;&#34;, delay_factor=1
 ):
     &#34;&#34;&#34;Sets self.base_prompt
@@ -5287,6 +5371,7 @@ Try to determine the device type.</p>
 <li><code><a title="netmiko.ssh_autodetect" href="ssh_autodetect.html">netmiko.ssh_autodetect</a></code></li>
 <li><code><a title="netmiko.ssh_exception" href="ssh_exception.html">netmiko.ssh_exception</a></code></li>
 <li><code><a title="netmiko.terminal_server" href="terminal_server/index.html">netmiko.terminal_server</a></code></li>
+<li><code><a title="netmiko.tplink" href="tplink/index.html">netmiko.tplink</a></code></li>
 <li><code><a title="netmiko.ubiquiti" href="ubiquiti/index.html">netmiko.ubiquiti</a></code></li>
 <li><code><a title="netmiko.utilities" href="utilities.html">netmiko.utilities</a></code></li>
 <li><code><a title="netmiko.vyos" href="vyos/index.html">netmiko.vyos</a></code></li>
diff --git a/docs/netmiko/linux/index.html b/docs/netmiko/linux/index.html
index 5787922237d3c3d69371921de89e7a91dc2d578c..e7d1dc9668e2340af0296b2aa0398a04760c8ff8 100644
--- a/docs/netmiko/linux/index.html
+++ b/docs/netmiko/linux/index.html
@@ -456,7 +456,7 @@ __all__ = [&#34;LinuxSSH&#34;, &#34;LinuxFileTransfer&#34;]</code></pre>
 </details>
 </dd>
 <dt id="netmiko.linux.LinuxSSH.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='sudo -s', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='sudo -s', pattern='ssword', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Attempt to become root.</p></section>
diff --git a/docs/netmiko/linux/linux_ssh.html b/docs/netmiko/linux/linux_ssh.html
index df22010106b8122ca3120069e9a8e87c3940b204..ea20fa72f89a68e46c44e5dc814f35fb5a89e7a8 100644
--- a/docs/netmiko/linux/linux_ssh.html
+++ b/docs/netmiko/linux/linux_ssh.html
@@ -622,7 +622,7 @@ class LinuxFileTransfer(CiscoFileTransfer):
 </details>
 </dd>
 <dt id="netmiko.linux.linux_ssh.LinuxSSH.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='sudo -s', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='sudo -s', pattern='ssword', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Attempt to become root.</p></section>
diff --git a/docs/netmiko/mellanox/index.html b/docs/netmiko/mellanox/index.html
index 2734337037a80129e7ba2e0eecaf08380ee1f568..1a096d111c5abb4a545033365f05b67ae8cdf2ad 100644
--- a/docs/netmiko/mellanox/index.html
+++ b/docs/netmiko/mellanox/index.html
@@ -246,7 +246,7 @@ __all__ = [&#34;MellanoxMlnxosSSH&#34;]</code></pre>
 <h3>Methods</h3>
 <dl>
 <dt id="netmiko.mellanox.MellanoxMlnxosSSH.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='#', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='#', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter into enable mode.</p></section>
diff --git a/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html b/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html
index 3706ca0c4d5c9d2ca6949c951f5faa68fd0ece2b..2265ddab4077b5822309acb03e9d0f341f6a3a5f 100644
--- a/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html
+++ b/docs/netmiko/mellanox/mellanox_mlnxos_ssh.html
@@ -298,7 +298,7 @@ class MellanoxMlnxosSSH(CiscoSSHConnection):
 <h3>Methods</h3>
 <dl>
 <dt id="netmiko.mellanox.mellanox_mlnxos_ssh.MellanoxMlnxosSSH.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='#', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='#', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter into enable mode.</p></section>
diff --git a/docs/netmiko/mrv/index.html b/docs/netmiko/mrv/index.html
index 7240ff88024c02690a18b8e292d1212f84dadf07..5b943685828e277f60600bab7e6df62f9944317e 100644
--- a/docs/netmiko/mrv/index.html
+++ b/docs/netmiko/mrv/index.html
@@ -494,7 +494,7 @@ __all__ = [&#34;MrvOptiswitchSSH&#34;, &#34;MrvLxSSH&#34;]</code></pre>
 <h3>Methods</h3>
 <dl>
 <dt id="netmiko.mrv.MrvOptiswitchSSH.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='#', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='#', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enable mode on MRV uses no password.</p></section>
diff --git a/docs/netmiko/mrv/mrv_ssh.html b/docs/netmiko/mrv/mrv_ssh.html
index 884d51b82d1f27f5f1e7249f507604bd4b8bb168..229094cd6ab4e44de1c30a7e298f984c9fe642f7 100644
--- a/docs/netmiko/mrv/mrv_ssh.html
+++ b/docs/netmiko/mrv/mrv_ssh.html
@@ -259,7 +259,7 @@ class MrvOptiswitchSSH(CiscoSSHConnection):
 <h3>Methods</h3>
 <dl>
 <dt id="netmiko.mrv.mrv_ssh.MrvOptiswitchSSH.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='#', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='#', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enable mode on MRV uses no password.</p></section>
diff --git a/docs/netmiko/nokia/index.html b/docs/netmiko/nokia/index.html
index c4cc956af223ea1854b31f5892dd597ecb097a5f..dfffb52e269eafab307deb6827e37bbd182f8c53 100644
--- a/docs/netmiko/nokia/index.html
+++ b/docs/netmiko/nokia/index.html
@@ -683,7 +683,7 @@ __all__ = [&#34;NokiaSrosSSH&#34;, &#34;NokiaSrosFileTransfer&#34;]</code></pre>
 </details>
 </dd>
 <dt id="netmiko.nokia.NokiaSrosSSH.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='ssword', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enable SR OS administrative mode</p></section>
diff --git a/docs/netmiko/nokia/nokia_sros_ssh.html b/docs/netmiko/nokia/nokia_sros_ssh.html
index 0f59ad2dec186e901c5f2c91256ce6e2abf205b9..3482f633654e3d22714d5953ec67238f3ff60fbb 100644
--- a/docs/netmiko/nokia/nokia_sros_ssh.html
+++ b/docs/netmiko/nokia/nokia_sros_ssh.html
@@ -989,7 +989,7 @@ class NokiaSrosFileTransfer(BaseFileTransfer):
 </details>
 </dd>
 <dt id="netmiko.nokia.nokia_sros_ssh.NokiaSrosSSH.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='ssword', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='ssword', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enable SR OS administrative mode</p></section>
diff --git a/docs/netmiko/paloalto/paloalto_panos.html b/docs/netmiko/paloalto/paloalto_panos.html
index 4954f1d95c6b8251a247679ac3c1a53a7020d948..8f7df22fee020a42abcdc1c32f2dfcb8c319b549 100644
--- a/docs/netmiko/paloalto/paloalto_panos.html
+++ b/docs/netmiko/paloalto/paloalto_panos.html
@@ -75,6 +75,7 @@ class PaloAltoPanosBase(BaseConnection):
 
     def commit(
         self,
+        comment=None,
         force=False,
         partial=False,
         device_and_network=False,
@@ -111,6 +112,8 @@ class PaloAltoPanosBase(BaseConnection):
         # Select proper command string based on arguments provided
         command_string = &#34;commit&#34;
         commit_marker = &#34;configuration committed successfully&#34;
+        if comment:
+            command_string += f&#39; description &#34;{comment}&#34;&#39;
         if force:
             command_string += &#34; force&#34;
         if partial:
@@ -402,6 +405,7 @@ Overrides several methods for PaloAlto-specific compatibility.</p>
 
     def commit(
         self,
+        comment=None,
         force=False,
         partial=False,
         device_and_network=False,
@@ -438,6 +442,8 @@ Overrides several methods for PaloAlto-specific compatibility.</p>
         # Select proper command string based on arguments provided
         command_string = &#34;commit&#34;
         commit_marker = &#34;configuration committed successfully&#34;
+        if comment:
+            command_string += f&#39; description &#34;{comment}&#34;&#39;
         if force:
             command_string += &#34; force&#34;
         if partial:
@@ -578,7 +584,7 @@ Overrides several methods for PaloAlto-specific compatibility.</p>
 </details>
 </dd>
 <dt id="netmiko.paloalto.paloalto_panos.PaloAltoPanosBase.commit"><code class="name flex">
-<span>def <span class="ident">commit</span></span>(<span>self, force=False, partial=False, device_and_network=False, policy_and_objects=False, vsys='', no_vsys=False, delay_factor=0.1)</span>
+<span>def <span class="ident">commit</span></span>(<span>self, comment=None, force=False, partial=False, device_and_network=False, policy_and_objects=False, vsys='', no_vsys=False, delay_factor=0.1)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Commit the candidate configuration.</p>
@@ -594,6 +600,7 @@ Exception</p></section>
 <summary>Source code</summary>
 <pre><code class="python">def commit(
     self,
+    comment=None,
     force=False,
     partial=False,
     device_and_network=False,
@@ -630,6 +637,8 @@ Exception</p></section>
     # Select proper command string based on arguments provided
     command_string = &#34;commit&#34;
     commit_marker = &#34;configuration committed successfully&#34;
+    if comment:
+        command_string += f&#39; description &#34;{comment}&#34;&#39;
     if force:
         command_string += &#34; force&#34;
     if partial:
diff --git a/docs/netmiko/ruckus/ruckus_fastiron.html b/docs/netmiko/ruckus/ruckus_fastiron.html
index 9b6a4565ac57ab008b98ffd9b636f07bfaf08828..b868f32c7ba4ba3945dd52120c96993e27d1af26 100644
--- a/docs/netmiko/ruckus/ruckus_fastiron.html
+++ b/docs/netmiko/ruckus/ruckus_fastiron.html
@@ -347,7 +347,7 @@ class RuckusFastironSSH(RuckusFastironBase):
 <h3>Methods</h3>
 <dl>
 <dt id="netmiko.ruckus.ruckus_fastiron.RuckusFastironBase.enable"><code class="name flex">
-<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='(ssword|User Name)', re_flags=<RegexFlag.IGNORECASE: 2>)</span>
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='enable', pattern='(ssword|User Name)', re_flags=re.IGNORECASE)</span>
 </code></dt>
 <dd>
 <section class="desc"><p>Enter enable mode.
diff --git a/docs/netmiko/scp_functions.html b/docs/netmiko/scp_functions.html
index 1630108d354dae46610a6911bee14c70271f7823..4c025687328db363179e11bfabf46aff2d0620f3 100644
--- a/docs/netmiko/scp_functions.html
+++ b/docs/netmiko/scp_functions.html
@@ -37,7 +37,8 @@ from netmiko import FileTransfer, InLineTransfer
 
 def progress_bar(filename, size, sent, peername=None):
     max_width = 50
-    filename = filename.decode()
+    if isinstance(filename, bytes):
+        filename = filename.decode()
     clear_screen = chr(27) + &#34;[2J&#34;
     terminating_char = &#34;|&#34;
 
@@ -300,7 +301,8 @@ def file_transfer(
 <summary>Source code</summary>
 <pre><code class="python">def progress_bar(filename, size, sent, peername=None):
     max_width = 50
-    filename = filename.decode()
+    if isinstance(filename, bytes):
+        filename = filename.decode()
     clear_screen = chr(27) + &#34;[2J&#34;
     terminating_char = &#34;|&#34;
 
diff --git a/docs/netmiko/tplink/index.html b/docs/netmiko/tplink/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..1fd93ecf1eacad859764b924818cced2fad33fb2
--- /dev/null
+++ b/docs/netmiko/tplink/index.html
@@ -0,0 +1,549 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.6.3" />
+<title>netmiko.tplink API documentation</title>
+<meta name="description" content="" />
+<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
+<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
+<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
+<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>netmiko.tplink</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">from netmiko.tplink.tplink_jetstream import TPLinkJetStreamSSH, TPLinkJetStreamTelnet
+
+__all__ = [&#34;TPLinkJetStreamSSH&#34;, &#34;TPLinkJetStreamTelnet&#34;]</code></pre>
+</details>
+</section>
+<section>
+<h2 class="section-title" id="header-submodules">Sub-modules</h2>
+<dl>
+<dt><code class="name"><a title="netmiko.tplink.tplink_jetstream" href="tplink_jetstream.html">netmiko.tplink.tplink_jetstream</a></code></dt>
+<dd>
+<section class="desc"></section>
+</dd>
+</dl>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-classes">Classes</h2>
+<dl>
+<dt id="netmiko.tplink.TPLinkJetStreamSSH"><code class="flex name class">
+<span>class <span class="ident">TPLinkJetStreamSSH</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Base Class for cisco-like behavior.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class TPLinkJetStreamSSH(TPLinkJetStreamBase):
+    def _override_check_dsa_parameters(parameters):
+        &#34;&#34;&#34;
+        Override check_dsa_parameters from cryptography&#39;s dsa.py
+
+        Without this the error below occurs:
+
+        ValueError: p must be exactly 1024, 2048, or 3072 bits long
+
+        Allows for shorter or longer parameters.p to be returned
+        from the server&#39;s host key. This is a HORRIBLE hack and a
+        security risk, please remove if possible!
+
+        By now, with firmware:
+
+        2.0.5 Build 20200109 Rel.36203(s)
+
+        It&#39;s still not possible to remove this hack.
+        &#34;&#34;&#34;
+        if crypto_utils.bit_length(parameters.q) not in [160, 256]:
+            raise ValueError(&#34;q must be exactly 160 or 256 bits long&#34;)
+
+        if not (1 &lt; parameters.g &lt; parameters.p):
+            raise ValueError(&#34;g, p don&#39;t satisfy 1 &lt; g &lt; p.&#34;)
+
+    dsa._check_dsa_parameters = _override_check_dsa_parameters</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable">enable</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation">session_preparation</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt">set_base_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
+<dt id="netmiko.tplink.TPLinkJetStreamTelnet"><code class="flex name class">
+<span>class <span class="ident">TPLinkJetStreamTelnet</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Base Class for cisco-like behavior.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class TPLinkJetStreamTelnet(TPLinkJetStreamBase):
+    def telnet_login(
+        self,
+        pri_prompt_terminator=&#34;#&#34;,
+        alt_prompt_terminator=&#34;&gt;&#34;,
+        username_pattern=r&#34;User:&#34;,
+        pwd_pattern=r&#34;Password:&#34;,
+        delay_factor=1,
+        max_loops=60,
+    ):
+        &#34;&#34;&#34;Telnet login: can be username/password or just password.&#34;&#34;&#34;
+        super().telnet_login(
+            pri_prompt_terminator=pri_prompt_terminator,
+            alt_prompt_terminator=alt_prompt_terminator,
+            username_pattern=username_pattern,
+            pwd_pattern=pwd_pattern,
+            delay_factor=delay_factor,
+            max_loops=max_loops,
+        )</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Methods</h3>
+<dl>
+<dt id="netmiko.tplink.TPLinkJetStreamTelnet.telnet_login"><code class="name flex">
+<span>def <span class="ident">telnet_login</span></span>(<span>self, pri_prompt_terminator='#', alt_prompt_terminator='>', username_pattern='User:', pwd_pattern='Password:', delay_factor=1, max_loops=60)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Telnet login: can be username/password or just password.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def telnet_login(
+    self,
+    pri_prompt_terminator=&#34;#&#34;,
+    alt_prompt_terminator=&#34;&gt;&#34;,
+    username_pattern=r&#34;User:&#34;,
+    pwd_pattern=r&#34;Password:&#34;,
+    delay_factor=1,
+    max_loops=60,
+):
+    &#34;&#34;&#34;Telnet login: can be username/password or just password.&#34;&#34;&#34;
+    super().telnet_login(
+        pri_prompt_terminator=pri_prompt_terminator,
+        alt_prompt_terminator=alt_prompt_terminator,
+        username_pattern=username_pattern,
+        pwd_pattern=pwd_pattern,
+        delay_factor=delay_factor,
+        max_loops=max_loops,
+    )</code></pre>
+</details>
+</dd>
+</dl>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable">enable</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation">session_preparation</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt" href="tplink_jetstream.html#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt">set_base_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
+</dl>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="netmiko" href="../index.html">netmiko</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-submodules">Sub-modules</a></h3>
+<ul>
+<li><code><a title="netmiko.tplink.tplink_jetstream" href="tplink_jetstream.html">netmiko.tplink.tplink_jetstream</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-classes">Classes</a></h3>
+<ul>
+<li>
+<h4><code><a title="netmiko.tplink.TPLinkJetStreamSSH" href="#netmiko.tplink.TPLinkJetStreamSSH">TPLinkJetStreamSSH</a></code></h4>
+</li>
+<li>
+<h4><code><a title="netmiko.tplink.TPLinkJetStreamTelnet" href="#netmiko.tplink.TPLinkJetStreamTelnet">TPLinkJetStreamTelnet</a></code></h4>
+<ul class="">
+<li><code><a title="netmiko.tplink.TPLinkJetStreamTelnet.telnet_login" href="#netmiko.tplink.TPLinkJetStreamTelnet.telnet_login">telnet_login</a></code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p>
+</footer>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
+<script>hljs.initHighlightingOnLoad()</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/netmiko/tplink/tplink_jetstream.html b/docs/netmiko/tplink/tplink_jetstream.html
new file mode 100644
index 0000000000000000000000000000000000000000..f345b0fca93ccaa1bd3c884321e07b7f67fdaa84
--- /dev/null
+++ b/docs/netmiko/tplink/tplink_jetstream.html
@@ -0,0 +1,1186 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.6.3" />
+<title>netmiko.tplink.tplink_jetstream API documentation</title>
+<meta name="description" content="" />
+<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
+<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
+<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
+<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>netmiko.tplink.tplink_jetstream</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">import re
+import time
+
+from cryptography import utils as crypto_utils
+from cryptography.hazmat.primitives.asymmetric import dsa
+
+from netmiko import log
+from netmiko.cisco_base_connection import CiscoSSHConnection
+from netmiko.ssh_exception import NetmikoTimeoutException
+
+
+class TPLinkJetStreamBase(CiscoSSHConnection):
+    def __init__(self, **kwargs):
+        # TP-Link doesn&#39;t have a way to set terminal width which breaks cmd_verify
+        if kwargs.get(&#34;global_cmd_verify&#34;) is None:
+            kwargs[&#34;global_cmd_verify&#34;] = False
+        # TP-Link uses &#34;\r\n&#34; as default_enter for SSH and Telnet
+        if kwargs.get(&#34;default_enter&#34;) is None:
+            kwargs[&#34;default_enter&#34;] = &#34;\r\n&#34;
+        return super().__init__(**kwargs)
+
+    def session_preparation(self):
+        &#34;&#34;&#34;
+        Prepare the session after the connection has been established.
+        &#34;&#34;&#34;
+        delay_factor = self.select_delay_factor(delay_factor=0)
+        time.sleep(0.3 * delay_factor)
+        self.clear_buffer()
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        self.set_base_prompt()
+        self.enable()
+        self.disable_paging()
+        # Clear the read buffer
+        time.sleep(0.3 * self.global_delay_factor)
+        self.clear_buffer()
+
+    def enable(self, cmd=&#34;&#34;, pattern=&#34;ssword&#34;, re_flags=re.IGNORECASE):
+        &#34;&#34;&#34;
+        TPLink JetStream requires you to first execute &#34;enable&#34; and then execute &#34;enable-admin&#34;.
+        This is necessary as &#34;configure&#34; is generally only available at &#34;enable-admin&#34; level
+
+        If the user does not have the Admin role, he will need to execute enable-admin to really
+        enable all functions.
+        &#34;&#34;&#34;
+
+        # If end-user passes in &#34;cmd&#34; execute that using normal process.
+        if cmd:
+            return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+        output = &#34;&#34;
+        msg = (
+            &#34;Failed to enter enable mode. Please ensure you pass &#34;
+            &#34;the &#39;secret&#39; argument to ConnectHandler.&#34;
+        )
+
+        cmds = [&#34;enable&#34;, &#34;enable-admin&#34;]
+        if not self.check_enable_mode():
+            for cmd in cmds:
+                self.write_channel(self.normalize_cmd(cmd))
+                try:
+                    output += self.read_until_prompt_or_pattern(
+                        pattern=pattern, re_flags=re_flags
+                    )
+                    self.write_channel(self.normalize_cmd(self.secret))
+                    output += self.read_until_prompt()
+                except NetmikoTimeoutException:
+                    raise ValueError(msg)
+                if not self.check_enable_mode():
+                    raise ValueError(msg)
+        return output
+
+    def config_mode(self, config_command=&#34;configure&#34;):
+        &#34;&#34;&#34;Enter configuration mode.&#34;&#34;&#34;
+        return super().config_mode(config_command=config_command)
+
+    def exit_config_mode(self, exit_config=&#34;exit&#34;, pattern=r&#34;#&#34;):
+        &#34;&#34;&#34;
+        Exit config mode.
+
+        Like the Mellanox equipment, the TP-Link Jetstream does not
+        support a single command to completely exit the configuration mode.
+
+        Consequently, need to keep checking and sending &#34;exit&#34;.
+        &#34;&#34;&#34;
+        output = &#34;&#34;
+        check_count = 12
+        while check_count &gt;= 0:
+            if self.check_config_mode():
+                self.write_channel(self.normalize_cmd(exit_config))
+                output += self.read_until_pattern(pattern=pattern)
+            else:
+                break
+            check_count -= 1
+
+        if self.check_config_mode():
+            raise ValueError(&#34;Failed to exit configuration mode&#34;)
+            log.debug(f&#34;exit_config_mode: {output}&#34;)
+
+        return output
+
+    def check_config_mode(self, check_string=&#34;(config&#34;, pattern=r&#34;#&#34;):
+        &#34;&#34;&#34;Check whether device is in configuration mode. Return a boolean.&#34;&#34;&#34;
+        return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+    def set_base_prompt(
+        self, pri_prompt_terminator=&#34;&gt;&#34;, alt_prompt_terminator=&#34;#&#34;, delay_factor=1
+    ):
+        &#34;&#34;&#34;
+        Sets self.base_prompt
+
+        Used as delimiter for stripping of trailing prompt in output.
+
+        Should be set to something that is general and applies in multiple
+        contexts. For TP-Link this will be the router prompt with &gt; or #
+        stripped off.
+
+        This will be set on logging in, but not when entering system-view
+        &#34;&#34;&#34;
+        return super().set_base_prompt(
+            pri_prompt_terminator=pri_prompt_terminator,
+            alt_prompt_terminator=alt_prompt_terminator,
+            delay_factor=delay_factor,
+        )
+
+
+class TPLinkJetStreamSSH(TPLinkJetStreamBase):
+    def _override_check_dsa_parameters(parameters):
+        &#34;&#34;&#34;
+        Override check_dsa_parameters from cryptography&#39;s dsa.py
+
+        Without this the error below occurs:
+
+        ValueError: p must be exactly 1024, 2048, or 3072 bits long
+
+        Allows for shorter or longer parameters.p to be returned
+        from the server&#39;s host key. This is a HORRIBLE hack and a
+        security risk, please remove if possible!
+
+        By now, with firmware:
+
+        2.0.5 Build 20200109 Rel.36203(s)
+
+        It&#39;s still not possible to remove this hack.
+        &#34;&#34;&#34;
+        if crypto_utils.bit_length(parameters.q) not in [160, 256]:
+            raise ValueError(&#34;q must be exactly 160 or 256 bits long&#34;)
+
+        if not (1 &lt; parameters.g &lt; parameters.p):
+            raise ValueError(&#34;g, p don&#39;t satisfy 1 &lt; g &lt; p.&#34;)
+
+    dsa._check_dsa_parameters = _override_check_dsa_parameters
+
+
+class TPLinkJetStreamTelnet(TPLinkJetStreamBase):
+    def telnet_login(
+        self,
+        pri_prompt_terminator=&#34;#&#34;,
+        alt_prompt_terminator=&#34;&gt;&#34;,
+        username_pattern=r&#34;User:&#34;,
+        pwd_pattern=r&#34;Password:&#34;,
+        delay_factor=1,
+        max_loops=60,
+    ):
+        &#34;&#34;&#34;Telnet login: can be username/password or just password.&#34;&#34;&#34;
+        super().telnet_login(
+            pri_prompt_terminator=pri_prompt_terminator,
+            alt_prompt_terminator=alt_prompt_terminator,
+            username_pattern=username_pattern,
+            pwd_pattern=pwd_pattern,
+            delay_factor=delay_factor,
+            max_loops=max_loops,
+        )</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-classes">Classes</h2>
+<dl>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase"><code class="flex name class">
+<span>class <span class="ident">TPLinkJetStreamBase</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Base Class for cisco-like behavior.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class TPLinkJetStreamBase(CiscoSSHConnection):
+    def __init__(self, **kwargs):
+        # TP-Link doesn&#39;t have a way to set terminal width which breaks cmd_verify
+        if kwargs.get(&#34;global_cmd_verify&#34;) is None:
+            kwargs[&#34;global_cmd_verify&#34;] = False
+        # TP-Link uses &#34;\r\n&#34; as default_enter for SSH and Telnet
+        if kwargs.get(&#34;default_enter&#34;) is None:
+            kwargs[&#34;default_enter&#34;] = &#34;\r\n&#34;
+        return super().__init__(**kwargs)
+
+    def session_preparation(self):
+        &#34;&#34;&#34;
+        Prepare the session after the connection has been established.
+        &#34;&#34;&#34;
+        delay_factor = self.select_delay_factor(delay_factor=0)
+        time.sleep(0.3 * delay_factor)
+        self.clear_buffer()
+        self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+        self.set_base_prompt()
+        self.enable()
+        self.disable_paging()
+        # Clear the read buffer
+        time.sleep(0.3 * self.global_delay_factor)
+        self.clear_buffer()
+
+    def enable(self, cmd=&#34;&#34;, pattern=&#34;ssword&#34;, re_flags=re.IGNORECASE):
+        &#34;&#34;&#34;
+        TPLink JetStream requires you to first execute &#34;enable&#34; and then execute &#34;enable-admin&#34;.
+        This is necessary as &#34;configure&#34; is generally only available at &#34;enable-admin&#34; level
+
+        If the user does not have the Admin role, he will need to execute enable-admin to really
+        enable all functions.
+        &#34;&#34;&#34;
+
+        # If end-user passes in &#34;cmd&#34; execute that using normal process.
+        if cmd:
+            return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+        output = &#34;&#34;
+        msg = (
+            &#34;Failed to enter enable mode. Please ensure you pass &#34;
+            &#34;the &#39;secret&#39; argument to ConnectHandler.&#34;
+        )
+
+        cmds = [&#34;enable&#34;, &#34;enable-admin&#34;]
+        if not self.check_enable_mode():
+            for cmd in cmds:
+                self.write_channel(self.normalize_cmd(cmd))
+                try:
+                    output += self.read_until_prompt_or_pattern(
+                        pattern=pattern, re_flags=re_flags
+                    )
+                    self.write_channel(self.normalize_cmd(self.secret))
+                    output += self.read_until_prompt()
+                except NetmikoTimeoutException:
+                    raise ValueError(msg)
+                if not self.check_enable_mode():
+                    raise ValueError(msg)
+        return output
+
+    def config_mode(self, config_command=&#34;configure&#34;):
+        &#34;&#34;&#34;Enter configuration mode.&#34;&#34;&#34;
+        return super().config_mode(config_command=config_command)
+
+    def exit_config_mode(self, exit_config=&#34;exit&#34;, pattern=r&#34;#&#34;):
+        &#34;&#34;&#34;
+        Exit config mode.
+
+        Like the Mellanox equipment, the TP-Link Jetstream does not
+        support a single command to completely exit the configuration mode.
+
+        Consequently, need to keep checking and sending &#34;exit&#34;.
+        &#34;&#34;&#34;
+        output = &#34;&#34;
+        check_count = 12
+        while check_count &gt;= 0:
+            if self.check_config_mode():
+                self.write_channel(self.normalize_cmd(exit_config))
+                output += self.read_until_pattern(pattern=pattern)
+            else:
+                break
+            check_count -= 1
+
+        if self.check_config_mode():
+            raise ValueError(&#34;Failed to exit configuration mode&#34;)
+            log.debug(f&#34;exit_config_mode: {output}&#34;)
+
+        return output
+
+    def check_config_mode(self, check_string=&#34;(config&#34;, pattern=r&#34;#&#34;):
+        &#34;&#34;&#34;Check whether device is in configuration mode. Return a boolean.&#34;&#34;&#34;
+        return super().check_config_mode(check_string=check_string, pattern=pattern)
+
+    def set_base_prompt(
+        self, pri_prompt_terminator=&#34;&gt;&#34;, alt_prompt_terminator=&#34;#&#34;, delay_factor=1
+    ):
+        &#34;&#34;&#34;
+        Sets self.base_prompt
+
+        Used as delimiter for stripping of trailing prompt in output.
+
+        Should be set to something that is general and applies in multiple
+        contexts. For TP-Link this will be the router prompt with &gt; or #
+        stripped off.
+
+        This will be set on logging in, but not when entering system-view
+        &#34;&#34;&#34;
+        return super().set_base_prompt(
+            pri_prompt_terminator=pri_prompt_terminator,
+            alt_prompt_terminator=alt_prompt_terminator,
+            delay_factor=delay_factor,
+        )</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Subclasses</h3>
+<ul class="hlist">
+<li><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamSSH" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamSSH">TPLinkJetStreamSSH</a></li>
+<li><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamTelnet" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamTelnet">TPLinkJetStreamTelnet</a></li>
+</ul>
+<h3>Methods</h3>
+<dl>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode"><code class="name flex">
+<span>def <span class="ident">check_config_mode</span></span>(<span>self, check_string='(config', pattern='#')</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Check whether device is in configuration mode. Return a boolean.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def check_config_mode(self, check_string=&#34;(config&#34;, pattern=r&#34;#&#34;):
+    &#34;&#34;&#34;Check whether device is in configuration mode. Return a boolean.&#34;&#34;&#34;
+    return super().check_config_mode(check_string=check_string, pattern=pattern)</code></pre>
+</details>
+</dd>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode"><code class="name flex">
+<span>def <span class="ident">config_mode</span></span>(<span>self, config_command='configure')</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Enter configuration mode.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def config_mode(self, config_command=&#34;configure&#34;):
+    &#34;&#34;&#34;Enter configuration mode.&#34;&#34;&#34;
+    return super().config_mode(config_command=config_command)</code></pre>
+</details>
+</dd>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable"><code class="name flex">
+<span>def <span class="ident">enable</span></span>(<span>self, cmd='', pattern='ssword', re_flags=re.IGNORECASE)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>TPLink JetStream requires you to first execute "enable" and then execute "enable-admin".
+This is necessary as "configure" is generally only available at "enable-admin" level</p>
+<p>If the user does not have the Admin role, he will need to execute enable-admin to really
+enable all functions.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def enable(self, cmd=&#34;&#34;, pattern=&#34;ssword&#34;, re_flags=re.IGNORECASE):
+    &#34;&#34;&#34;
+    TPLink JetStream requires you to first execute &#34;enable&#34; and then execute &#34;enable-admin&#34;.
+    This is necessary as &#34;configure&#34; is generally only available at &#34;enable-admin&#34; level
+
+    If the user does not have the Admin role, he will need to execute enable-admin to really
+    enable all functions.
+    &#34;&#34;&#34;
+
+    # If end-user passes in &#34;cmd&#34; execute that using normal process.
+    if cmd:
+        return super().enable(cmd=cmd, pattern=pattern, re_flags=re_flags)
+
+    output = &#34;&#34;
+    msg = (
+        &#34;Failed to enter enable mode. Please ensure you pass &#34;
+        &#34;the &#39;secret&#39; argument to ConnectHandler.&#34;
+    )
+
+    cmds = [&#34;enable&#34;, &#34;enable-admin&#34;]
+    if not self.check_enable_mode():
+        for cmd in cmds:
+            self.write_channel(self.normalize_cmd(cmd))
+            try:
+                output += self.read_until_prompt_or_pattern(
+                    pattern=pattern, re_flags=re_flags
+                )
+                self.write_channel(self.normalize_cmd(self.secret))
+                output += self.read_until_prompt()
+            except NetmikoTimeoutException:
+                raise ValueError(msg)
+            if not self.check_enable_mode():
+                raise ValueError(msg)
+    return output</code></pre>
+</details>
+</dd>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode"><code class="name flex">
+<span>def <span class="ident">exit_config_mode</span></span>(<span>self, exit_config='exit', pattern='#')</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Exit config mode.</p>
+<p>Like the Mellanox equipment, the TP-Link Jetstream does not
+support a single command to completely exit the configuration mode.</p>
+<p>Consequently, need to keep checking and sending "exit".</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def exit_config_mode(self, exit_config=&#34;exit&#34;, pattern=r&#34;#&#34;):
+    &#34;&#34;&#34;
+    Exit config mode.
+
+    Like the Mellanox equipment, the TP-Link Jetstream does not
+    support a single command to completely exit the configuration mode.
+
+    Consequently, need to keep checking and sending &#34;exit&#34;.
+    &#34;&#34;&#34;
+    output = &#34;&#34;
+    check_count = 12
+    while check_count &gt;= 0:
+        if self.check_config_mode():
+            self.write_channel(self.normalize_cmd(exit_config))
+            output += self.read_until_pattern(pattern=pattern)
+        else:
+            break
+        check_count -= 1
+
+    if self.check_config_mode():
+        raise ValueError(&#34;Failed to exit configuration mode&#34;)
+        log.debug(f&#34;exit_config_mode: {output}&#34;)
+
+    return output</code></pre>
+</details>
+</dd>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation"><code class="name flex">
+<span>def <span class="ident">session_preparation</span></span>(<span>self)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Prepare the session after the connection has been established.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def session_preparation(self):
+    &#34;&#34;&#34;
+    Prepare the session after the connection has been established.
+    &#34;&#34;&#34;
+    delay_factor = self.select_delay_factor(delay_factor=0)
+    time.sleep(0.3 * delay_factor)
+    self.clear_buffer()
+    self._test_channel_read(pattern=r&#34;[&gt;#]&#34;)
+    self.set_base_prompt()
+    self.enable()
+    self.disable_paging()
+    # Clear the read buffer
+    time.sleep(0.3 * self.global_delay_factor)
+    self.clear_buffer()</code></pre>
+</details>
+</dd>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt"><code class="name flex">
+<span>def <span class="ident">set_base_prompt</span></span>(<span>self, pri_prompt_terminator='>', alt_prompt_terminator='#', delay_factor=1)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Sets self.base_prompt</p>
+<p>Used as delimiter for stripping of trailing prompt in output.</p>
+<p>Should be set to something that is general and applies in multiple
+contexts. For TP-Link this will be the router prompt with &gt; or #
+stripped off.</p>
+<p>This will be set on logging in, but not when entering system-view</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def set_base_prompt(
+    self, pri_prompt_terminator=&#34;&gt;&#34;, alt_prompt_terminator=&#34;#&#34;, delay_factor=1
+):
+    &#34;&#34;&#34;
+    Sets self.base_prompt
+
+    Used as delimiter for stripping of trailing prompt in output.
+
+    Should be set to something that is general and applies in multiple
+    contexts. For TP-Link this will be the router prompt with &gt; or #
+    stripped off.
+
+    This will be set on logging in, but not when entering system-view
+    &#34;&#34;&#34;
+    return super().set_base_prompt(
+        pri_prompt_terminator=pri_prompt_terminator,
+        alt_prompt_terminator=alt_prompt_terminator,
+        delay_factor=delay_factor,
+    )</code></pre>
+</details>
+</dd>
+</dl>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li>
+<li><code><a title="netmiko.cisco_base_connection.CiscoSSHConnection.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamSSH"><code class="flex name class">
+<span>class <span class="ident">TPLinkJetStreamSSH</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Base Class for cisco-like behavior.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class TPLinkJetStreamSSH(TPLinkJetStreamBase):
+    def _override_check_dsa_parameters(parameters):
+        &#34;&#34;&#34;
+        Override check_dsa_parameters from cryptography&#39;s dsa.py
+
+        Without this the error below occurs:
+
+        ValueError: p must be exactly 1024, 2048, or 3072 bits long
+
+        Allows for shorter or longer parameters.p to be returned
+        from the server&#39;s host key. This is a HORRIBLE hack and a
+        security risk, please remove if possible!
+
+        By now, with firmware:
+
+        2.0.5 Build 20200109 Rel.36203(s)
+
+        It&#39;s still not possible to remove this hack.
+        &#34;&#34;&#34;
+        if crypto_utils.bit_length(parameters.q) not in [160, 256]:
+            raise ValueError(&#34;q must be exactly 160 or 256 bits long&#34;)
+
+        if not (1 &lt; parameters.g &lt; parameters.p):
+            raise ValueError(&#34;g, p don&#39;t satisfy 1 &lt; g &lt; p.&#34;)
+
+    dsa._check_dsa_parameters = _override_check_dsa_parameters</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable">enable</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation">session_preparation</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt">set_base_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamTelnet"><code class="flex name class">
+<span>class <span class="ident">TPLinkJetStreamTelnet</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Base Class for cisco-like behavior.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class TPLinkJetStreamTelnet(TPLinkJetStreamBase):
+    def telnet_login(
+        self,
+        pri_prompt_terminator=&#34;#&#34;,
+        alt_prompt_terminator=&#34;&gt;&#34;,
+        username_pattern=r&#34;User:&#34;,
+        pwd_pattern=r&#34;Password:&#34;,
+        delay_factor=1,
+        max_loops=60,
+    ):
+        &#34;&#34;&#34;Telnet login: can be username/password or just password.&#34;&#34;&#34;
+        super().telnet_login(
+            pri_prompt_terminator=pri_prompt_terminator,
+            alt_prompt_terminator=alt_prompt_terminator,
+            username_pattern=username_pattern,
+            pwd_pattern=pwd_pattern,
+            delay_factor=delay_factor,
+            max_loops=max_loops,
+        )</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Methods</h3>
+<dl>
+<dt id="netmiko.tplink.tplink_jetstream.TPLinkJetStreamTelnet.telnet_login"><code class="name flex">
+<span>def <span class="ident">telnet_login</span></span>(<span>self, pri_prompt_terminator='#', alt_prompt_terminator='>', username_pattern='User:', pwd_pattern='Password:', delay_factor=1, max_loops=60)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Telnet login: can be username/password or just password.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def telnet_login(
+    self,
+    pri_prompt_terminator=&#34;#&#34;,
+    alt_prompt_terminator=&#34;&gt;&#34;,
+    username_pattern=r&#34;User:&#34;,
+    pwd_pattern=r&#34;Password:&#34;,
+    delay_factor=1,
+    max_loops=60,
+):
+    &#34;&#34;&#34;Telnet login: can be username/password or just password.&#34;&#34;&#34;
+    super().telnet_login(
+        pri_prompt_terminator=pri_prompt_terminator,
+        alt_prompt_terminator=alt_prompt_terminator,
+        username_pattern=username_pattern,
+        pwd_pattern=pwd_pattern,
+        delay_factor=delay_factor,
+        max_loops=max_loops,
+    )</code></pre>
+</details>
+</dd>
+</dl>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.commit" href="../base_connection.html#netmiko.base_connection.BaseConnection.commit">commit</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable">enable</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_enable_mode" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.save_config" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.save_config">save_config</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.send_config_set" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation">session_preparation</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt">set_base_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
+</dl>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="netmiko.tplink" href="index.html">netmiko.tplink</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-classes">Classes</a></h3>
+<ul>
+<li>
+<h4><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase">TPLinkJetStreamBase</a></code></h4>
+<ul class="two-column">
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.enable">enable</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.session_preparation">session_preparation</a></code></li>
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamBase.set_base_prompt">set_base_prompt</a></code></li>
+</ul>
+</li>
+<li>
+<h4><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamSSH" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamSSH">TPLinkJetStreamSSH</a></code></h4>
+</li>
+<li>
+<h4><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamTelnet" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamTelnet">TPLinkJetStreamTelnet</a></code></h4>
+<ul class="">
+<li><code><a title="netmiko.tplink.tplink_jetstream.TPLinkJetStreamTelnet.telnet_login" href="#netmiko.tplink.tplink_jetstream.TPLinkJetStreamTelnet.telnet_login">telnet_login</a></code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p>
+</footer>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
+<script>hljs.initHighlightingOnLoad()</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/netmiko/ubiquiti/edgerouter_ssh.html b/docs/netmiko/ubiquiti/edgerouter_ssh.html
new file mode 100644
index 0000000000000000000000000000000000000000..6fb2f9cd25bc436119373f66aabcab636e2cb3fa
--- /dev/null
+++ b/docs/netmiko/ubiquiti/edgerouter_ssh.html
@@ -0,0 +1,328 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.6.3" />
+<title>netmiko.ubiquiti.edgerouter_ssh API documentation</title>
+<meta name="description" content="" />
+<link href='https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css' rel='stylesheet'>
+<link href='https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/8.0.0/sanitize.min.css' rel='stylesheet'>
+<link href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" rel="stylesheet">
+<style>.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{font-weight:bold}#index h4 + ul{margin-bottom:.6em}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase;cursor:pointer}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>netmiko.ubiquiti.edgerouter_ssh</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">import time
+from netmiko.vyos.vyos_ssh import VyOSSSH
+
+
+class UbiquitiEdgeRouterSSH(VyOSSSH):
+    &#34;&#34;&#34;Implement methods for interacting with EdgeOS EdgeRouter network devices.&#34;&#34;&#34;
+
+    def session_preparation(self):
+        &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
+        self._test_channel_read()
+        self.set_base_prompt()
+        self.set_terminal_width(command=&#34;terminal width 512&#34;)
+        self.disable_paging(command=&#34;terminal length 0&#34;)
+        # Clear the read buffer
+        time.sleep(0.3 * self.global_delay_factor)
+        self.clear_buffer()
+
+    def save_config(self, cmd=&#34;save&#34;, confirm=False, confirm_response=&#34;&#34;):
+        &#34;&#34;&#34;Saves Config.&#34;&#34;&#34;
+        if confirm is True:
+            raise ValueError(&#34;EdgeRouter does not support save_config confirmation.&#34;)
+        output = self.send_command(command_string=cmd)
+        if &#34;Done&#34; not in output:
+            raise ValueError(f&#34;Save failed with following errors:\n\n{output}&#34;)
+        return output</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-classes">Classes</h2>
+<dl>
+<dt id="netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH"><code class="flex name class">
+<span>class <span class="ident">UbiquitiEdgeRouterSSH</span></span>
+<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Implement methods for interacting with EdgeOS EdgeRouter network devices.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class UbiquitiEdgeRouterSSH(VyOSSSH):
+    &#34;&#34;&#34;Implement methods for interacting with EdgeOS EdgeRouter network devices.&#34;&#34;&#34;
+
+    def session_preparation(self):
+        &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
+        self._test_channel_read()
+        self.set_base_prompt()
+        self.set_terminal_width(command=&#34;terminal width 512&#34;)
+        self.disable_paging(command=&#34;terminal length 0&#34;)
+        # Clear the read buffer
+        time.sleep(0.3 * self.global_delay_factor)
+        self.clear_buffer()
+
+    def save_config(self, cmd=&#34;save&#34;, confirm=False, confirm_response=&#34;&#34;):
+        &#34;&#34;&#34;Saves Config.&#34;&#34;&#34;
+        if confirm is True:
+            raise ValueError(&#34;EdgeRouter does not support save_config confirmation.&#34;)
+        output = self.send_command(command_string=cmd)
+        if &#34;Done&#34; not in output:
+            raise ValueError(f&#34;Save failed with following errors:\n\n{output}&#34;)
+        return output</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.vyos.vyos_ssh.VyOSSSH" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH">VyOSSSH</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Methods</h3>
+<dl>
+<dt id="netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH.save_config"><code class="name flex">
+<span>def <span class="ident">save_config</span></span>(<span>self, cmd='save', confirm=False, confirm_response='')</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Saves Config.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def save_config(self, cmd=&#34;save&#34;, confirm=False, confirm_response=&#34;&#34;):
+    &#34;&#34;&#34;Saves Config.&#34;&#34;&#34;
+    if confirm is True:
+        raise ValueError(&#34;EdgeRouter does not support save_config confirmation.&#34;)
+    output = self.send_command(command_string=cmd)
+    if &#34;Done&#34; not in output:
+        raise ValueError(f&#34;Save failed with following errors:\n\n{output}&#34;)
+    return output</code></pre>
+</details>
+</dd>
+</dl>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.vyos.vyos_ssh.VyOSSSH" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH">VyOSSSH</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.check_config_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.check_enable_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.commit" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.commit">commit</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.config_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.enable" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.enable">enable</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.exit_config_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.exit_enable_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_config_set" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.session_preparation" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.session_preparation">session_preparation</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.set_base_prompt" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.set_base_prompt">set_base_prompt</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
+</dl>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="netmiko.ubiquiti" href="index.html">netmiko.ubiquiti</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-classes">Classes</a></h3>
+<ul>
+<li>
+<h4><code><a title="netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH" href="#netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH">UbiquitiEdgeRouterSSH</a></code></h4>
+<ul class="">
+<li><code><a title="netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH.save_config" href="#netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH.save_config">save_config</a></code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.6.3</a>.</p>
+</footer>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
+<script>hljs.initHighlightingOnLoad()</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/docs/netmiko/ubiquiti/index.html b/docs/netmiko/ubiquiti/index.html
index 57d42e1808c05ac02714e5cf99607beed1367794..9827fde534967c910cfb1d3fd6df8e90788d3723 100644
--- a/docs/netmiko/ubiquiti/index.html
+++ b/docs/netmiko/ubiquiti/index.html
@@ -23,9 +23,15 @@
 <details class="source">
 <summary>Source code</summary>
 <pre><code class="python">from netmiko.ubiquiti.edge_ssh import UbiquitiEdgeSSH
+from netmiko.ubiquiti.edgerouter_ssh import UbiquitiEdgeRouterSSH
 from netmiko.ubiquiti.unifiswitch_ssh import UbiquitiUnifiSwitchSSH
 
-__all__ = [&#34;UbiquitiEdgeSSH&#34;, &#34;UnifiSwitchSSH&#34;, &#34;UbiquitiUnifiSwitchSSH&#34;]</code></pre>
+__all__ = [
+    &#34;UbiquitiEdgeRouterSSH&#34;,
+    &#34;UbiquitiEdgeSSH&#34;,
+    &#34;UnifiSwitchSSH&#34;,
+    &#34;UbiquitiUnifiSwitchSSH&#34;,
+]</code></pre>
 </details>
 </section>
 <section>
@@ -35,6 +41,10 @@ __all__ = [&#34;UbiquitiEdgeSSH&#34;, &#34;UnifiSwitchSSH&#34;, &#34;UbiquitiUni
 <dd>
 <section class="desc"></section>
 </dd>
+<dt><code class="name"><a title="netmiko.ubiquiti.edgerouter_ssh" href="edgerouter_ssh.html">netmiko.ubiquiti.edgerouter_ssh</a></code></dt>
+<dd>
+<section class="desc"></section>
+</dd>
 <dt><code class="name"><a title="netmiko.ubiquiti.unifiswitch_ssh" href="unifiswitch_ssh.html">netmiko.ubiquiti.unifiswitch_ssh</a></code></dt>
 <dd>
 <section class="desc"></section>
@@ -48,6 +58,240 @@ __all__ = [&#34;UbiquitiEdgeSSH&#34;, &#34;UnifiSwitchSSH&#34;, &#34;UbiquitiUni
 <section>
 <h2 class="section-title" id="header-classes">Classes</h2>
 <dl>
+<dt id="netmiko.ubiquiti.UbiquitiEdgeRouterSSH"><code class="flex name class">
+<span>class <span class="ident">UbiquitiEdgeRouterSSH</span></span>
+<span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Implement methods for interacting with EdgeOS EdgeRouter network devices.</p>
+<pre><code>    Initialize attributes for establishing connection to target device.
+
+    :param ip: IP address of target device. Not required if `host` is
+        provided.
+    :type ip: str
+
+    :param host: Hostname of target device. Not required if `ip` is
+            provided.
+    :type host: str
+
+    :param username: Username to authenticate against target device if
+            required.
+    :type username: str
+
+    :param password: Password to authenticate against target device if
+            required.
+    :type password: str
+
+    :param secret: The enable password if target device requires one.
+    :type secret: str
+
+    :param port: The destination port used to connect to the target
+            device.
+    :type port: int or None
+
+    :param device_type: Class selection based on device type.
+    :type device_type: str
+
+    :param verbose: Enable additional messages to standard output.
+    :type verbose: bool
+
+    :param global_delay_factor: Multiplication factor affecting Netmiko delays (default: 1).
+    :type global_delay_factor: int
+
+    :param use_keys: Connect to target device using SSH keys.
+    :type use_keys: bool
+
+    :param key_file: Filename path of the SSH key file to use.
+    :type key_file: str
+
+    :param pkey: SSH key object to use.
+    :type pkey: paramiko.PKey
+
+    :param passphrase: Passphrase to use for encrypted key; password will be used for key
+            decryption if not specified.
+    :type passphrase: str
+
+    :param allow_agent: Enable use of SSH key-agent.
+    :type allow_agent: bool
+
+    :param ssh_strict: Automatically reject unknown SSH host keys (default: False, which
+            means unknown SSH host keys will be accepted).
+    :type ssh_strict: bool
+
+    :param system_host_keys: Load host keys from the users known_hosts file.
+    :type system_host_keys: bool
+    :param alt_host_keys: If `True` host keys will be loaded from the file specified in
+            alt_key_file.
+    :type alt_host_keys: bool
+
+    :param alt_key_file: SSH host key file to use (if alt_host_keys=True).
+    :type alt_key_file: str
+
+    :param ssh_config_file: File name of OpenSSH configuration file.
+    :type ssh_config_file: str
+
+    :param timeout: Connection timeout.
+    :type timeout: float
+
+    :param session_timeout: Set a timeout for parallel requests.
+    :type session_timeout: float
+
+    :param auth_timeout: Set a timeout (in seconds) to wait for an authentication response.
+    :type auth_timeout: float
+
+    :param banner_timeout: Set a timeout to wait for the SSH banner (pass to Paramiko).
+    :type banner_timeout: float
+
+    :param keepalive: Send SSH keepalive packets at a specific interval, in seconds.
+            Currently defaults to 0, for backwards compatibility (it will not attempt
+            to keep the connection alive).
+    :type keepalive: int
+
+    :param default_enter: Character(s) to send to correspond to enter key (default:
+</code></pre>
+<p>).
+:type default_enter: str</p>
+<pre><code>    :param response_return: Character(s) to use in normalized return data to represent
+            enter key (default:
+</code></pre>
+<p>)
+:type response_return: str</p>
+<pre><code>    :param fast_cli: Provide a way to optimize for performance. Converts select_delay_factor
+            to select smallest of global and specific. Sets default global_delay_factor to .1
+            (default: False)
+    :type fast_cli: boolean
+
+    :param session_log: File path or BufferedIOBase subclass object to write the session log to.
+    :type session_log: str
+
+    :param session_log_record_writes: The session log generally only records channel reads due
+            to eliminate command duplication due to command echo. You can enable this if you
+            want to record both channel reads and channel writes in the log (default: False).
+    :type session_log_record_writes: boolean
+
+    :param session_log_file_mode: "write" or "append" for session_log file mode
+            (default: "write")
+    :type session_log_file_mode: str
+
+    :param allow_auto_change: Allow automatic configuration changes for terminal settings.
+            (default: False)
+    :type allow_auto_change: bool
+
+    :param encoding: Encoding to be used when writing bytes to the output channel.
+            (default: ascii)
+    :type encoding: str
+
+    :param sock: An open socket or socket-like object (such as a `.Channel`) to use for
+            communication to the target host (default: None).
+    :type sock: socket
+
+    :param global_cmd_verify: Control whether command echo verification is enabled or disabled
+            (default: None). Global attribute takes precedence over function `cmd_verify`
+            argument. Value of `None` indicates to use function `cmd_verify` argument.
+    :type global_cmd_verify: bool|None
+
+    :param auto_connect: Control whether Netmiko automatically establishes the connection as
+            part of the object creation (default: True).
+    :type auto_connect: bool
+</code></pre></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">class UbiquitiEdgeRouterSSH(VyOSSSH):
+    &#34;&#34;&#34;Implement methods for interacting with EdgeOS EdgeRouter network devices.&#34;&#34;&#34;
+
+    def session_preparation(self):
+        &#34;&#34;&#34;Prepare the session after the connection has been established.&#34;&#34;&#34;
+        self._test_channel_read()
+        self.set_base_prompt()
+        self.set_terminal_width(command=&#34;terminal width 512&#34;)
+        self.disable_paging(command=&#34;terminal length 0&#34;)
+        # Clear the read buffer
+        time.sleep(0.3 * self.global_delay_factor)
+        self.clear_buffer()
+
+    def save_config(self, cmd=&#34;save&#34;, confirm=False, confirm_response=&#34;&#34;):
+        &#34;&#34;&#34;Saves Config.&#34;&#34;&#34;
+        if confirm is True:
+            raise ValueError(&#34;EdgeRouter does not support save_config confirmation.&#34;)
+        output = self.send_command(command_string=cmd)
+        if &#34;Done&#34; not in output:
+            raise ValueError(f&#34;Save failed with following errors:\n\n{output}&#34;)
+        return output</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="netmiko.vyos.vyos_ssh.VyOSSSH" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH">VyOSSSH</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoSSHConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoSSHConnection">CiscoSSHConnection</a></li>
+<li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
+<li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
+</ul>
+<h3>Methods</h3>
+<dl>
+<dt id="netmiko.ubiquiti.UbiquitiEdgeRouterSSH.save_config"><code class="name flex">
+<span>def <span class="ident">save_config</span></span>(<span>self, cmd='save', confirm=False, confirm_response='')</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Saves Config.</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def save_config(self, cmd=&#34;save&#34;, confirm=False, confirm_response=&#34;&#34;):
+    &#34;&#34;&#34;Saves Config.&#34;&#34;&#34;
+    if confirm is True:
+        raise ValueError(&#34;EdgeRouter does not support save_config confirmation.&#34;)
+    output = self.send_command(command_string=cmd)
+    if &#34;Done&#34; not in output:
+        raise ValueError(f&#34;Save failed with following errors:\n\n{output}&#34;)
+    return output</code></pre>
+</details>
+</dd>
+</dl>
+<h3>Inherited members</h3>
+<ul class="hlist">
+<li><code><b><a title="netmiko.vyos.vyos_ssh.VyOSSSH" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH">VyOSSSH</a></b></code>:
+<ul class="hlist">
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.check_config_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.check_config_mode">check_config_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.check_enable_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.check_enable_mode">check_enable_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.cleanup" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.cleanup">cleanup</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.clear_buffer" href="../base_connection.html#netmiko.base_connection.BaseConnection.clear_buffer">clear_buffer</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.close_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.close_session_log">close_session_log</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.commit" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.commit">commit</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.config_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.config_mode">config_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.disable_paging" href="../base_connection.html#netmiko.base_connection.BaseConnection.disable_paging">disable_paging</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.disconnect" href="../base_connection.html#netmiko.base_connection.BaseConnection.disconnect">disconnect</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.enable" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.enable">enable</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.establish_connection" href="../base_connection.html#netmiko.base_connection.BaseConnection.establish_connection">establish_connection</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.exit_config_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.exit_config_mode">exit_config_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.exit_enable_mode" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.exit_enable_mode">exit_enable_mode</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.find_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.find_prompt">find_prompt</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.is_alive" href="../base_connection.html#netmiko.base_connection.BaseConnection.is_alive">is_alive</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.normalize_cmd" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_cmd">normalize_cmd</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.normalize_linefeeds" href="../base_connection.html#netmiko.base_connection.BaseConnection.normalize_linefeeds">normalize_linefeeds</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.open_session_log" href="../base_connection.html#netmiko.base_connection.BaseConnection.open_session_log">open_session_log</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.paramiko_cleanup" href="../base_connection.html#netmiko.base_connection.BaseConnection.paramiko_cleanup">paramiko_cleanup</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.read_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_channel">read_channel</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.read_until_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_pattern">read_until_pattern</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.read_until_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt">read_until_prompt</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.read_until_prompt_or_pattern" href="../base_connection.html#netmiko.base_connection.BaseConnection.read_until_prompt_or_pattern">read_until_prompt_or_pattern</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.select_delay_factor" href="../base_connection.html#netmiko.base_connection.BaseConnection.select_delay_factor">select_delay_factor</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command">send_command</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_command_expect" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_expect">send_command_expect</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_command_timing" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_command_timing">send_command_timing</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_config_from_file" href="../base_connection.html#netmiko.base_connection.BaseConnection.send_config_from_file">send_config_from_file</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.send_config_set" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.send_config_set">send_config_set</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.session_preparation" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.session_preparation">session_preparation</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.set_base_prompt" href="../vyos/vyos_ssh.html#netmiko.vyos.vyos_ssh.VyOSSSH.set_base_prompt">set_base_prompt</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.set_terminal_width" href="../base_connection.html#netmiko.base_connection.BaseConnection.set_terminal_width">set_terminal_width</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.special_login_handler" href="../base_connection.html#netmiko.base_connection.BaseConnection.special_login_handler">special_login_handler</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.strip_ansi_escape_codes" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_ansi_escape_codes">strip_ansi_escape_codes</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.strip_backspaces" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_backspaces">strip_backspaces</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.strip_command" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_command">strip_command</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.strip_prompt" href="../base_connection.html#netmiko.base_connection.BaseConnection.strip_prompt">strip_prompt</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.telnet_login" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection.telnet_login">telnet_login</a></code></li>
+<li><code><a title="netmiko.vyos.vyos_ssh.VyOSSSH.write_channel" href="../base_connection.html#netmiko.base_connection.BaseConnection.write_channel">write_channel</a></code></li>
+</ul>
+</li>
+</ul>
+</dd>
 <dt id="netmiko.ubiquiti.UbiquitiEdgeSSH"><code class="flex name class">
 <span>class <span class="ident">UbiquitiEdgeSSH</span></span>
 <span>(</span><span>ip='', host='', username='', password=None, secret='', port=None, device_type='', verbose=False, global_delay_factor=1, global_cmd_verify=None, use_keys=False, key_file=None, pkey=None, passphrase=None, allow_agent=False, ssh_strict=False, system_host_keys=False, alt_host_keys=False, alt_key_file='', ssh_config_file=None, conn_timeout=5, auth_timeout=None, banner_timeout=15, blocking_timeout=20, timeout=100, session_timeout=60, keepalive=0, default_enter=None, response_return=None, serial_settings=None, fast_cli=False, session_log=None, session_log_record_writes=False, session_log_file_mode='write', allow_auto_change=False, encoding='ascii', sock=None, auto_connect=True)</span>
@@ -634,12 +878,19 @@ environment.</p></section>
 <li><h3><a href="#header-submodules">Sub-modules</a></h3>
 <ul>
 <li><code><a title="netmiko.ubiquiti.edge_ssh" href="edge_ssh.html">netmiko.ubiquiti.edge_ssh</a></code></li>
+<li><code><a title="netmiko.ubiquiti.edgerouter_ssh" href="edgerouter_ssh.html">netmiko.ubiquiti.edgerouter_ssh</a></code></li>
 <li><code><a title="netmiko.ubiquiti.unifiswitch_ssh" href="unifiswitch_ssh.html">netmiko.ubiquiti.unifiswitch_ssh</a></code></li>
 </ul>
 </li>
 <li><h3><a href="#header-classes">Classes</a></h3>
 <ul>
 <li>
+<h4><code><a title="netmiko.ubiquiti.UbiquitiEdgeRouterSSH" href="#netmiko.ubiquiti.UbiquitiEdgeRouterSSH">UbiquitiEdgeRouterSSH</a></code></h4>
+<ul class="">
+<li><code><a title="netmiko.ubiquiti.UbiquitiEdgeRouterSSH.save_config" href="#netmiko.ubiquiti.UbiquitiEdgeRouterSSH.save_config">save_config</a></code></li>
+</ul>
+</li>
+<li>
 <h4><code><a title="netmiko.ubiquiti.UbiquitiEdgeSSH" href="#netmiko.ubiquiti.UbiquitiEdgeSSH">UbiquitiEdgeSSH</a></code></h4>
 <ul class="">
 <li><code><a title="netmiko.ubiquiti.UbiquitiEdgeSSH.check_config_mode" href="#netmiko.ubiquiti.UbiquitiEdgeSSH.check_config_mode">check_config_mode</a></code></li>
diff --git a/docs/netmiko/utilities.html b/docs/netmiko/utilities.html
index 15806fbeab4369e654e900cd78feca54d464b82c..f60fb6700cade37143231640bcac7d419e898ca0 100644
--- a/docs/netmiko/utilities.html
+++ b/docs/netmiko/utilities.html
@@ -34,6 +34,14 @@ from datetime import datetime
 from netmiko._textfsm import _clitable as clitable
 from netmiko._textfsm._clitable import CliTableError
 
+try:
+    from ttp import ttp
+
+    TTP_INSTALLED = True
+
+except ImportError:
+    TTP_INSTALLED = False
+
 try:
     from genie.conf.base import Device
     from genie.libs.parser.utils import get_parser
@@ -43,6 +51,12 @@ try:
 except ImportError:
     GENIE_INSTALLED = False
 
+# If we are on python &lt; 3.7, we need to force the import of importlib.resources backport
+try:
+    from importlib.resources import path as importresources_path
+except ModuleNotFoundError:
+    from importlib_resources import path as importresources_path
+
 try:
     import serial.tools.list_ports
 
@@ -50,7 +64,6 @@ try:
 except ImportError:
     PYSERIAL_INSTALLED = False
 
-
 # Dictionary mapping &#39;show run&#39; for vendors with different command
 SHOW_RUN_MAPPER = {
     &#34;juniper&#34;: &#34;show configuration&#34;,
@@ -134,8 +147,8 @@ def find_cfg_file(file_name=None):
         if files:
             return files[0]
     raise IOError(
-        &#34;.netmiko.yml file not found in NETMIKO_TOOLS environment variable directory, current &#34;
-        &#34;directory, or home directory.&#34;
+        &#34;.netmiko.yml file not found in NETMIKO_TOOLS environment variable directory,&#34;
+        &#34; current directory, or home directory.&#34;
     )
 
 
@@ -249,25 +262,59 @@ def check_serial_port(name):
         raise ValueError(msg)
 
 
-def get_template_dir():
-    &#34;&#34;&#34;Find and return the ntc-templates/templates dir.&#34;&#34;&#34;
-    try:
-        template_dir = os.path.expanduser(os.environ[&#34;NET_TEXTFSM&#34;])
+def get_template_dir(_skip_ntc_package=False):
+    &#34;&#34;&#34;
+    Find and return the directory containing the TextFSM index file.
+
+    Order of preference is:
+    1) Find directory in `NET_TEXTFSM` Environment Variable.
+    2) Check for pip installed `ntc-templates` location in this environment.
+    3) ~/ntc-templates/templates.
+
+    If `index` file is not found in any of these locations, raise ValueError
+
+    :return: directory containing the TextFSM index file
+
+    &#34;&#34;&#34;
+
+    msg = &#34;&#34;&#34;
+Directory containing TextFSM index file not found.
+
+Please set the NET_TEXTFSM environment variable to point at the directory containing your TextFSM
+index file.
+
+Alternatively, `pip install ntc-templates` (if using ntc-templates).
+
+&#34;&#34;&#34;
+
+    # Try NET_TEXTFSM environment variable
+    template_dir = os.environ.get(&#34;NET_TEXTFSM&#34;)
+    if template_dir is not None:
+        template_dir = os.path.expanduser(template_dir)
         index = os.path.join(template_dir, &#34;index&#34;)
         if not os.path.isfile(index):
             # Assume only base ./ntc-templates specified
             template_dir = os.path.join(template_dir, &#34;templates&#34;)
-    except KeyError:
-        # Construct path ~/ntc-templates/templates
-        home_dir = os.path.expanduser(&#34;~&#34;)
-        template_dir = os.path.join(home_dir, &#34;ntc-templates&#34;, &#34;templates&#34;)
+
+    else:
+        # Try &#39;pip installed&#39; ntc-templates
+        try:
+            with importresources_path(
+                package=&#34;ntc_templates&#34;, resource=&#34;templates&#34;
+            ) as posix_path:
+                # Example: /opt/venv/netmiko/lib/python3.8/site-packages/ntc_templates/templates
+                template_dir = str(posix_path)
+                # This is for Netmiko automated testing
+                if _skip_ntc_package:
+                    raise ModuleNotFoundError()
+
+        except ModuleNotFoundError:
+            # Finally check in ~/ntc-templates/templates
+            home_dir = os.path.expanduser(&#34;~&#34;)
+            template_dir = os.path.join(home_dir, &#34;ntc-templates&#34;, &#34;templates&#34;)
 
     index = os.path.join(template_dir, &#34;index&#34;)
     if not os.path.isdir(template_dir) or not os.path.isfile(index):
-        msg = &#34;&#34;&#34;
-Valid ntc-templates not found, please install https://github.com/networktocode/ntc-templates
-and then set the NET_TEXTFSM environment variable to point to the ./ntc-templates/templates
-directory.&#34;&#34;&#34;
         raise ValueError(msg)
     return os.path.abspath(template_dir)
 
@@ -330,6 +377,25 @@ def get_structured_data(raw_output, platform=None, command=None, template=None):
         )
 
 
+def get_structured_data_ttp(raw_output, template=None):
+    &#34;&#34;&#34;
+    Convert raw CLI output to structured data using TTP template.
+
+    You can use a straight TextFSM file i.e. specify &#34;template&#34;
+    &#34;&#34;&#34;
+    if not TTP_INSTALLED:
+        msg = &#34;\nTTP is not installed. Please PIP install ttp:\n&#34; &#34;pip install ttp\n&#34;
+        raise ValueError(msg)
+
+    try:
+        if template:
+            ttp_parser = ttp(data=raw_output, template=template)
+            ttp_parser.parse(one=True)
+            return ttp_parser.result(format=&#34;raw&#34;)
+    except Exception:
+        return raw_output
+
+
 def get_structured_data_genie(raw_output, platform, command):
     if not sys.version_info &gt;= (3, 4):
         raise ValueError(&#34;Genie requires Python &gt;= 3.4&#34;)
@@ -370,7 +436,7 @@ def get_structured_data_genie(raw_output, platform, command):
     device.custom[&#34;abstraction&#34;][&#34;order&#34;] = [&#34;os&#34;]
     device.cli = AttrDict({&#34;execute&#34;: None})
     try:
-        # Test of whether their is a parser for the given command (will return Exception if fails)
+        # Test whether there is a parser for given command (return Exception if fails)
         get_parser(command, device)
         parsed_output = device.parse(command, output=raw_output)
         return parsed_output
@@ -573,8 +639,8 @@ Also allow NETMIKO_TOOLS_CFG to point directly at a file</p></section>
         if files:
             return files[0]
     raise IOError(
-        &#34;.netmiko.yml file not found in NETMIKO_TOOLS environment variable directory, current &#34;
-        &#34;directory, or home directory.&#34;
+        &#34;.netmiko.yml file not found in NETMIKO_TOOLS environment variable directory,&#34;
+        &#34; current directory, or home directory.&#34;
     )</code></pre>
 </details>
 </dd>
@@ -686,7 +752,7 @@ then you must use an CliTable index file.</p></section>
     device.custom[&#34;abstraction&#34;][&#34;order&#34;] = [&#34;os&#34;]
     device.cli = AttrDict({&#34;execute&#34;: None})
     try:
-        # Test of whether their is a parser for the given command (will return Exception if fails)
+        # Test whether there is a parser for given command (return Exception if fails)
         get_parser(command, device)
         parsed_output = device.parse(command, output=raw_output)
         return parsed_output
@@ -694,32 +760,99 @@ then you must use an CliTable index file.</p></section>
         return raw_output</code></pre>
 </details>
 </dd>
+<dt id="netmiko.utilities.get_structured_data_ttp"><code class="name flex">
+<span>def <span class="ident">get_structured_data_ttp</span></span>(<span>raw_output, template=None)</span>
+</code></dt>
+<dd>
+<section class="desc"><p>Convert raw CLI output to structured data using TTP template.</p>
+<p>You can use a straight TextFSM file i.e. specify "template"</p></section>
+<details class="source">
+<summary>Source code</summary>
+<pre><code class="python">def get_structured_data_ttp(raw_output, template=None):
+    &#34;&#34;&#34;
+    Convert raw CLI output to structured data using TTP template.
+
+    You can use a straight TextFSM file i.e. specify &#34;template&#34;
+    &#34;&#34;&#34;
+    if not TTP_INSTALLED:
+        msg = &#34;\nTTP is not installed. Please PIP install ttp:\n&#34; &#34;pip install ttp\n&#34;
+        raise ValueError(msg)
+
+    try:
+        if template:
+            ttp_parser = ttp(data=raw_output, template=template)
+            ttp_parser.parse(one=True)
+            return ttp_parser.result(format=&#34;raw&#34;)
+    except Exception:
+        return raw_output</code></pre>
+</details>
+</dd>
 <dt id="netmiko.utilities.get_template_dir"><code class="name flex">
 <span>def <span class="ident">get_template_dir</span></span>(<span>)</span>
 </code></dt>
 <dd>
-<section class="desc"><p>Find and return the ntc-templates/templates dir.</p></section>
+<section class="desc"><p>Find and return the directory containing the TextFSM index file.</p>
+<p>Order of preference is:
+1) Find directory in <code>NET_TEXTFSM</code> Environment Variable.
+2) Check for pip installed <code>ntc-templates</code> location in this environment.
+3) ~/ntc-templates/templates.</p>
+<p>If <code>index</code> file is not found in any of these locations, raise ValueError</p>
+<p>:return: directory containing the TextFSM index file</p></section>
 <details class="source">
 <summary>Source code</summary>
-<pre><code class="python">def get_template_dir():
-    &#34;&#34;&#34;Find and return the ntc-templates/templates dir.&#34;&#34;&#34;
-    try:
-        template_dir = os.path.expanduser(os.environ[&#34;NET_TEXTFSM&#34;])
+<pre><code class="python">def get_template_dir(_skip_ntc_package=False):
+    &#34;&#34;&#34;
+    Find and return the directory containing the TextFSM index file.
+
+    Order of preference is:
+    1) Find directory in `NET_TEXTFSM` Environment Variable.
+    2) Check for pip installed `ntc-templates` location in this environment.
+    3) ~/ntc-templates/templates.
+
+    If `index` file is not found in any of these locations, raise ValueError
+
+    :return: directory containing the TextFSM index file
+
+    &#34;&#34;&#34;
+
+    msg = &#34;&#34;&#34;
+Directory containing TextFSM index file not found.
+
+Please set the NET_TEXTFSM environment variable to point at the directory containing your TextFSM
+index file.
+
+Alternatively, `pip install ntc-templates` (if using ntc-templates).
+
+&#34;&#34;&#34;
+
+    # Try NET_TEXTFSM environment variable
+    template_dir = os.environ.get(&#34;NET_TEXTFSM&#34;)
+    if template_dir is not None:
+        template_dir = os.path.expanduser(template_dir)
         index = os.path.join(template_dir, &#34;index&#34;)
         if not os.path.isfile(index):
             # Assume only base ./ntc-templates specified
             template_dir = os.path.join(template_dir, &#34;templates&#34;)
-    except KeyError:
-        # Construct path ~/ntc-templates/templates
-        home_dir = os.path.expanduser(&#34;~&#34;)
-        template_dir = os.path.join(home_dir, &#34;ntc-templates&#34;, &#34;templates&#34;)
+
+    else:
+        # Try &#39;pip installed&#39; ntc-templates
+        try:
+            with importresources_path(
+                package=&#34;ntc_templates&#34;, resource=&#34;templates&#34;
+            ) as posix_path:
+                # Example: /opt/venv/netmiko/lib/python3.8/site-packages/ntc_templates/templates
+                template_dir = str(posix_path)
+                # This is for Netmiko automated testing
+                if _skip_ntc_package:
+                    raise ModuleNotFoundError()
+
+        except ModuleNotFoundError:
+            # Finally check in ~/ntc-templates/templates
+            home_dir = os.path.expanduser(&#34;~&#34;)
+            template_dir = os.path.join(home_dir, &#34;ntc-templates&#34;, &#34;templates&#34;)
 
     index = os.path.join(template_dir, &#34;index&#34;)
     if not os.path.isdir(template_dir) or not os.path.isfile(index):
-        msg = &#34;&#34;&#34;
-Valid ntc-templates not found, please install https://github.com/networktocode/ntc-templates
-and then set the NET_TEXTFSM environment variable to point to the ./ntc-templates/templates
-directory.&#34;&#34;&#34;
         raise ValueError(msg)
     return os.path.abspath(template_dir)</code></pre>
 </details>
@@ -890,6 +1023,7 @@ directory.&#34;&#34;&#34;
 <li><code><a title="netmiko.utilities.find_netmiko_dir" href="#netmiko.utilities.find_netmiko_dir">find_netmiko_dir</a></code></li>
 <li><code><a title="netmiko.utilities.get_structured_data" href="#netmiko.utilities.get_structured_data">get_structured_data</a></code></li>
 <li><code><a title="netmiko.utilities.get_structured_data_genie" href="#netmiko.utilities.get_structured_data_genie">get_structured_data_genie</a></code></li>
+<li><code><a title="netmiko.utilities.get_structured_data_ttp" href="#netmiko.utilities.get_structured_data_ttp">get_structured_data_ttp</a></code></li>
 <li><code><a title="netmiko.utilities.get_template_dir" href="#netmiko.utilities.get_template_dir">get_template_dir</a></code></li>
 <li><code><a title="netmiko.utilities.load_devices" href="#netmiko.utilities.load_devices">load_devices</a></code></li>
 <li><code><a title="netmiko.utilities.load_yaml_file" href="#netmiko.utilities.load_yaml_file">load_yaml_file</a></code></li>
diff --git a/docs/netmiko/vyos/index.html b/docs/netmiko/vyos/index.html
index 83dfe0cbc50109afa92167e4eaed9ec5f40ecec1..815a0eb884f2770aa3804e913b621ea3f010c69c 100644
--- a/docs/netmiko/vyos/index.html
+++ b/docs/netmiko/vyos/index.html
@@ -290,6 +290,10 @@ __all__ = [&#34;VyOSSSH&#34;]</code></pre>
 <li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
 <li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
 </ul>
+<h3>Subclasses</h3>
+<ul class="hlist">
+<li><a title="netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH" href="../ubiquiti/edgerouter_ssh.html#netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH">UbiquitiEdgeRouterSSH</a></li>
+</ul>
 <h3>Methods</h3>
 <dl>
 <dt id="netmiko.vyos.VyOSSSH.check_config_mode"><code class="name flex">
diff --git a/docs/netmiko/vyos/vyos_ssh.html b/docs/netmiko/vyos/vyos_ssh.html
index 093c9b6a0f3780e8cdafceb3b8faefa6f1bc40b2..1e9f27cc2493c189023fc56a02e3a4e1be2f6c23 100644
--- a/docs/netmiko/vyos/vyos_ssh.html
+++ b/docs/netmiko/vyos/vyos_ssh.html
@@ -386,6 +386,10 @@ class VyOSSSH(CiscoSSHConnection):
 <li><a title="netmiko.cisco_base_connection.CiscoBaseConnection" href="../cisco_base_connection.html#netmiko.cisco_base_connection.CiscoBaseConnection">CiscoBaseConnection</a></li>
 <li><a title="netmiko.base_connection.BaseConnection" href="../base_connection.html#netmiko.base_connection.BaseConnection">BaseConnection</a></li>
 </ul>
+<h3>Subclasses</h3>
+<ul class="hlist">
+<li><a title="netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH" href="../ubiquiti/edgerouter_ssh.html#netmiko.ubiquiti.edgerouter_ssh.UbiquitiEdgeRouterSSH">UbiquitiEdgeRouterSSH</a></li>
+</ul>
 <h3>Methods</h3>
 <dl>
 <dt id="netmiko.vyos.vyos_ssh.VyOSSSH.check_config_mode"><code class="name flex">