Pan-Python
Pan-Python is a multi-tool set for interacting with Palo Alto Networks PAN-OS, Panorama, WildFire, and AutoFocus platforms. It provides a powerful, low-level Python interface to the PAN-OS and Panorama XML API, as well as interfaces for WildFire, AutoFocus, and licensing APIs. The library is actively maintained, with its current version being 0.25.0, and receives regular updates.
Common errors
-
pan.xapi.PanXapiError: (403, 'Forbidden', None, None)
cause Incorrect API key or insufficient permissions for the API user on the Palo Alto Networks device.fixVerify the API key is correct and ensure the user associated with the key has the necessary administrative roles and permissions on the PAN-OS device or Panorama. -
ModuleNotFoundError: No module named 'pan'
cause The `pan-python` library is not installed, or the Python environment where it was installed is not active.fixInstall the package using `pip install pan-python` in your active Python environment. If using a virtual environment, ensure it is activated. -
AttributeError: 'PanXapi' object has no attribute 'some_method'
cause Attempting to call a method or access an attribute that does not exist on the `PanXapi` object, or mistyping a valid method name. This often happens when mixing `pan-python` (low-level) with `pan-os-python` (object-oriented SDK) calls.fixConsult the `pan-python` documentation for available methods and attributes on `PanXapi` and other classes. If attempting a higher-level operation, consider if `pan-os-python` would be more appropriate. -
KeyError: 'some_key'
cause Attempting to access a dictionary key that does not exist in the XML API response or a data structure derived from it.fixInspect the XML response structure from the device using `xapi.xml_result()` to confirm the exact key names. Use `.get('key_name', default_value)` for safer dictionary access.
Warnings
- breaking Python 2 support was entirely removed starting from v0.19.0. Pan-Python now strictly requires Python 3.7 or newer.
- gotcha When initializing `PanXapi`, providing both `api_key` and `api_username`/`api_password` is redundant. It is recommended to use only the `api_key` for authentication for simplicity and often better security practices.
- gotcha The `pan.xapi.PanXapi.import_file()` method, when used with `file` as bytes, requires a `filename` argument, even if it's a dummy string, as it's a required parameter.
- gotcha Using a large `nlog` value in `pan.xapi.PanXapi.log()` can lead to memory exceptions as the entire XML document is loaded into memory by the `ElementTree` module.
- gotcha `pan-python` provides a low-level XML API interface, while `pan-os-python` is an object-oriented SDK. Ensure you are using the correct library for your automation needs; `pan-os-python` typically offers a more abstract and user-friendly experience for configuration tasks.
Install
-
pip install pan-python
Imports
- PanXapi
from pan.xapi import PanXapi
- PanWFapi
from pan.wfapi import PanWFapi
- PanAFapi
from pan.afapi import PanAFapi
- PanLicapi
from pan.licapi import PanLicapi
Quickstart
import os
from pan.xapi import PanXapi, PanXapiError
hostname = os.environ.get('PAN_OS_HOSTNAME', 'your_firewall_ip')
api_key = os.environ.get('PAN_OS_API_KEY', 'your_api_key')
if not hostname or not api_key:
print("Please set PAN_OS_HOSTNAME and PAN_OS_API_KEY environment variables.")
exit(1)
try:
# Initialize the XAPI connection
xapi = PanXapi(hostname=hostname, api_key=api_key)
# Example 1: Execute an operational command (show system info)
print("\n--- Showing System Info ---")
xapi.op(cmd='show system info', cmd_xml=True)
if xapi.status == 'success':
print(xapi.xml_result())
else:
print(f"Error fetching system info: {xapi.status}: {xapi.status_detail}")
# Example 2: Edit a configuration element (e.g., disable a security rule)
# Note: This is a configuration change and requires appropriate permissions.
# For a real scenario, ensure rule 'rule7' exists and handle commit.
print("\n--- Attempting to disable 'rule7' ---")
xpath = "/config/devices/entry/vsys/entry/rulebase/security/rules/entry[@name='rule7']/disabled"
element = "<disabled>yes</disabled>"
# Example: Uncomment and adjust for your environment
# xapi.edit(xpath=xpath, element=element)
# if xapi.status == 'success':
# print("Rule 'rule7' disabled. Remember to commit changes.")
# else:
# print(f"Error disabling rule: {xapi.status}: {xapi.status_detail}")
except PanXapiError as e:
print(f"PanXapi Error: {e}")
except Exception as e:
print(f"An unexpected error occurred: {e}")