Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![GitHub issues](https://img.shields.io/github/issues/PaloAltoNetworks/prisma-sase-sdk-python.svg)](https://github.com/PaloAltoNetworks/prisma-sase-sdk-python/issues)


# Palo Alto Networks Prisma SASE Python SDK v6.6.2b1
# Palo Alto Networks Prisma SASE Python SDK v6.8.1b1

Python3 SDK for the Prisma SASE AppFabric

Expand Down Expand Up @@ -47,6 +47,7 @@ MIT
#### Version
| Version | Build | Changes |
|-----------| ----- |------------------------------------------------------------|
| **6.8.1** | **b1** | Support for July 2026 Controller release. |
| **6.6.2** | **b1** | Support for February 2026 Controller release. |
| **6.6.1** | **b1** | Support for October 2025 Controller release. |
| **6.5.2** | **b2** | Support for February 2025 Controller release with bugfixes. |
Expand Down
1 change: 1 addition & 0 deletions docs/ca_bundle.m.html
Original file line number Diff line number Diff line change
Expand Up @@ -2354,6 +2354,7 @@
.codehilite .cs { color: #808072 } /* Comment.Special */
.codehilite .gd { color: #A9B7C6 } /* Generic.Deleted */
.codehilite .ge { color: #808072; font-style: italic } /* Generic.Emph */
.codehilite .ges { color: #808072 } /* Generic.EmphStrong */
.codehilite .gr { color: #808072 } /* Generic.Error */
.codehilite .gh { color: #88BE05; font-weight: bold } /* Generic.Heading */
.codehilite .gi { color: #88BE05 } /* Generic.Inserted */
Expand Down
1,289 changes: 645 additions & 644 deletions docs/delete_api.m.html

Large diffs are not rendered by default.

3,853 changes: 2,080 additions & 1,773 deletions docs/get_api.m.html

Large diffs are not rendered by default.

467 changes: 234 additions & 233 deletions docs/index.html

Large diffs are not rendered by default.

140 changes: 78 additions & 62 deletions docs/interactive.m.html

Large diffs are not rendered by default.

59 changes: 34 additions & 25 deletions docs/patch_api.m.html

Large diffs are not rendered by default.

19,149 changes: 11,447 additions & 7,702 deletions docs/post_api.m.html

Large diffs are not rendered by default.

2,537 changes: 1,599 additions & 938 deletions docs/put_api.m.html

Large diffs are not rendered by default.

17 changes: 9 additions & 8 deletions docs/ws_api.m.html
Original file line number Diff line number Diff line change
Expand Up @@ -2356,6 +2356,7 @@
.codehilite .cs { color: #808072 } /* Comment.Special */
.codehilite .gd { color: #A9B7C6 } /* Generic.Deleted */
.codehilite .ge { color: #808072; font-style: italic } /* Generic.Emph */
.codehilite .ges { color: #808072 } /* Generic.EmphStrong */
.codehilite .gr { color: #808072 } /* Generic.Error */
.codehilite .gh { color: #88BE05; font-weight: bold } /* Generic.Heading */
.codehilite .gi { color: #88BE05 } /* Generic.Inserted */
Expand Down Expand Up @@ -2646,7 +2647,7 @@ <h1 class="title"><span class="name">prisma_sase.ws_api</span> module</h1>


<span class="k">class</span> <span class="nc">WebSockets</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Prisma SASE Python SDK - WebSocket Functions</span>

<span class="sd"> Object to handle WebSocket operations.</span>
Expand All @@ -2656,7 +2657,7 @@ <h1 class="title"><span class="name">prisma_sase.ws_api</span> module</h1>
<span class="n">_parent_class</span> <span class="o">=</span> <span class="kc">None</span>

<span class="k">def</span> <span class="nf">toolkit_session</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">element_id</span><span class="p">,</span> <span class="n">tenant_id</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">api_version</span><span class="o">=</span><span class="s2">&quot;v2.0&quot;</span><span class="p">,</span> <span class="n">cols</span><span class="o">=</span><span class="mi">207</span><span class="p">,</span> <span class="n">rows</span><span class="o">=</span><span class="mi">53</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Open a Toolkit Session WebSocket</span>

<span class="sd"> **Parameters:**:</span>
Expand Down Expand Up @@ -2687,7 +2688,7 @@ <h1 class="title"><span class="name">prisma_sase.ws_api</span> module</h1>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent_class</span><span class="o">.</span><span class="n">websocket_call</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tenant_id</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">api_version</span><span class="o">=</span><span class="s2">&quot;v2.0&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Open the default Tenant WebSocket for use in multiple functions.</span>

<span class="sd"> **Parameters:**:</span>
Expand Down Expand Up @@ -2744,7 +2745,7 @@ <h3 class="section-title" id="header-classes">Classes</h3>
<p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-prisma_sase.ws_api.WebSockets', this);">Show source &equiv;</a></p>
<div id="source-prisma_sase.ws_api.WebSockets" class="source">
<div class="codehilite"><pre><span></span><span class="k">class</span> <span class="nc">WebSockets</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Prisma SASE Python SDK - WebSocket Functions</span>

<span class="sd"> Object to handle WebSocket operations.</span>
Expand All @@ -2754,7 +2755,7 @@ <h3 class="section-title" id="header-classes">Classes</h3>
<span class="n">_parent_class</span> <span class="o">=</span> <span class="kc">None</span>

<span class="k">def</span> <span class="nf">toolkit_session</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">element_id</span><span class="p">,</span> <span class="n">tenant_id</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">api_version</span><span class="o">=</span><span class="s2">&quot;v2.0&quot;</span><span class="p">,</span> <span class="n">cols</span><span class="o">=</span><span class="mi">207</span><span class="p">,</span> <span class="n">rows</span><span class="o">=</span><span class="mi">53</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Open a Toolkit Session WebSocket</span>

<span class="sd"> **Parameters:**:</span>
Expand Down Expand Up @@ -2785,7 +2786,7 @@ <h3 class="section-title" id="header-classes">Classes</h3>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parent_class</span><span class="o">.</span><span class="n">websocket_call</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tenant_id</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">api_version</span><span class="o">=</span><span class="s2">&quot;v2.0&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Open the default Tenant WebSocket for use in multiple functions.</span>

<span class="sd"> **Parameters:**:</span>
Expand Down Expand Up @@ -2845,7 +2846,7 @@ <h3>Static methods</h3>
<p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-prisma_sase.ws_api.WebSockets.default', this);">Show source &equiv;</a></p>
<div id="source-prisma_sase.ws_api.WebSockets.default" class="source">
<div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">tenant_id</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">api_version</span><span class="o">=</span><span class="s2">&quot;v2.0&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Open the default Tenant WebSocket for use in multiple functions.</span>
<span class="sd"> **Parameters:**:</span>
<span class="sd"> - **tenant_id**: Tenant ID</span>
Expand Down Expand Up @@ -2896,7 +2897,7 @@ <h3>Static methods</h3>
<p class="source_link"><a href="javascript:void(0);" onclick="toggle('source-prisma_sase.ws_api.WebSockets.toolkit_session', this);">Show source &equiv;</a></p>
<div id="source-prisma_sase.ws_api.WebSockets.toolkit_session" class="source">
<div class="codehilite"><pre><span></span><span class="k">def</span> <span class="nf">toolkit_session</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">element_id</span><span class="p">,</span> <span class="n">tenant_id</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">api_version</span><span class="o">=</span><span class="s2">&quot;v2.0&quot;</span><span class="p">,</span> <span class="n">cols</span><span class="o">=</span><span class="mi">207</span><span class="p">,</span> <span class="n">rows</span><span class="o">=</span><span class="mi">53</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Open a Toolkit Session WebSocket</span>
<span class="sd"> **Parameters:**:</span>
<span class="sd"> - **element_id**: Element ID</span>
Expand Down
49 changes: 40 additions & 9 deletions prisma_sase/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
Python3 SDK for the Prisma SASE AppFabric

**Version:** v6.6.2b1
**Version:** v6.8.1b1

**Author:** Palo Alto Networks

Expand Down Expand Up @@ -161,7 +161,7 @@
"""websocket logger is handled slightly differently, so we will have a seperate handle."""

# Version of SDK
version = "6.6.2b1"
version = "6.8.1b1"
"""SDK Version string"""
__version__ = version

Expand Down Expand Up @@ -285,11 +285,25 @@ def jdout_detailed(api_response, sensitive=False):
output += "REQUEST BODY:\n{0}\n\n".format({})
else:
try:
# Attempt to load JSON from string to make it look beter.
output += "REQUEST BODY:\n{0}\n\n".format(json.dumps(json.loads(api_response.request.body), indent=4))
body_obj = json.loads(api_response.request.body)
if isinstance(body_obj, dict) and not sensitive:
_SENSITIVE_BODY_KEYS = {
'password', 'client_secret', 'secret', 'psk', 'pre_shared_key',
'community', 'auth_phrase', 'enc_phrase', 'priv_phrase',
'md5_secret', 'private_key', 'token', 'access_token',
'refresh_token', 'passphrase',
}
for bk in list(body_obj.keys()):
if bk.lower() in _SENSITIVE_BODY_KEYS:
body_obj[bk] = '<REDACTED>'
output += "REQUEST BODY:\n{0}\n\n".format(json.dumps(body_obj, indent=4))
except (TypeError, ValueError, AttributeError):
# if pretty call above didn't work, just toss it to jdout to best effort it.
output += "REQUEST BODY:\n{0}\n\n".format(jdout(api_response.request.body))
body_str = text_type(api_response.request.body)
if not sensitive:
body_str = re.sub(
r'((?:client_secret|password|secret|psk|token)=)[^&]+',
r'\1<REDACTED>', body_str)
output += "REQUEST BODY:\n{0}\n\n".format(body_str)
output += "RESPONSE: {0} {1}\n".format(api_response.status_code, api_response.reason)
output += "RESPONSE HEADERS:\n"
for key, value in api_response.headers.items():
Expand Down Expand Up @@ -1138,8 +1152,20 @@ def rest_call(self, url, method, data=None, sensitive=False, timeout=None, conte
# make request
try:
if not sensitive:
masked_headers = {}
for k, v in headers.items():
if k.lower() in ('authorization', 'x-auth-token'):
masked_headers[k] = v[:12] + '...<REDACTED>' if len(v) > 12 else '<REDACTED>'
else:
masked_headers[k] = v
masked_cookie = {}
for k, v in cookie.items():
if k.lower().startswith('auth_token'):
masked_cookie[k] = v[:8] + '...<REDACTED>' if len(v) > 8 else '<REDACTED>'
else:
masked_cookie[k] = v
api_logger.debug('\n\tREQUEST: %s %s\n\tHEADERS: %s\n\tCOOKIES: %s\n\tDATA: %s\n',
method.upper(), url, headers, cookie, data)
method.upper(), url, masked_headers, masked_cookie, data)

# Actual request
response = self._session.request(method, url, data=data, stream=True, timeout=timeout,
Expand Down Expand Up @@ -1813,7 +1839,8 @@ def _generate_jwt(self):

# call the login API.
response = self.rest_call(_shared_service_url, "post",
data=data, jsonify_data=False, content_json=False)
data=data, jsonify_data=False, content_json=False,
sensitive=True)

if response.sdk_status:
if 'access_token' not in response.sdk_content and not response.sdk_content.get('access_token'):
Expand All @@ -1830,7 +1857,7 @@ def _generate_jwt(self):
seconds=response.sdk_content.get('expires_in'))

# debug info if needed
api_logger.debug("ACCESS_TOKEN=%s", response.sdk_content.get('access_token'))
api_logger.debug("ACCESS_TOKEN=%s...(redacted)", text_type(access_token)[:16])

# Start setup of constructor.
session = self.expose_session()
Expand Down Expand Up @@ -1868,6 +1895,10 @@ def _refresh_jwt(self):
"""
if self.jwt_expires_in <= 60:
self._session = requests.Session()
# restore user's ssl_verify setting
self._session.verify = self.verify
# re-mount TlsHttpAdapter (ssl_context + retry)
self.update_session_adapter()
if self._generate_jwt():
api_logger.debug("Re-generated Token..")
self.use_jwt = False
Expand Down
Loading