Client Module
Overview
The SCM (Strata Cloud Manager) client module provides the primary interface for interacting with the Palo Alto Networks Strata Cloud Manager API. It handles authentication, request management, and provides a clean interface for making API calls with proper error handling and Pydantic model validation.
Starting with version 0.3.14, the SCM client supports a unified interface for accessing service objects through attribute-based access, allowing for a more intuitive and streamlined developer experience.
SCM Client
Class Definition
def __init__(
self,
client_id: str,
client_secret: str,
tsg_id: str,
api_base_url: str = "https://api.strata.paloaltonetworks.com",
token_url: str = "https://auth.apps.paloaltonetworks.com/am/oauth2/access_token",
log_level: str = "ERROR"
)
Attributes
Attribute | Type | Description |
---|---|---|
api_base_url |
str | Base URL for the API endpoints |
token_url |
str | URL for obtaining OAuth tokens |
oauth_client |
OAuth2Client | OAuth2 client handling authentication |
session |
requests.Session | HTTP session for making requests |
logger |
Logger | Logger instance for SDK logging |
Client Usage Patterns
The SDK supports two primary usage patterns:
Unified Client Interface (Recommended)
The unified client approach allows you to access all service objects directly through the client instance, providing a more intuitive and streamlined developer experience:
# Initialize client with your credentialsclient = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id",
# Optional parameters:
# token_url="https://custom.auth.server.com/oauth2/token"
)
# Access services directly through attributesclient.address.create({...})
client.tag.list(folder="Texas")
client.security_rule.get(rule_id)
This pattern offers several advantages: - Reduced code verbosity - Centralized client management - Automatic token refresh handling - No need to create multiple service instances - Consistent interface across all services
Traditional Service Instantiation (Legacy)
You can still use the traditional pattern where service objects are explicitly instantiated:
from scm.config.objects import Address
# Initialize clientclient = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id",
# Optional parameters:
# token_url="https://custom.auth.server.com/oauth2/token"
)
# Create service instance manuallyaddress_service = Address(client)
# Use the service instanceaddress_service.create({...})
Note
While the traditional pattern is still supported for backward compatibility, it's recommended to use the unified client interface for new development as it provides a more streamlined developer experience and ensures proper token refresh handling.
Available Services
The unified client provides access to all service objects in the SDK through attributes:
Objects
client.address
- IP addresses, CIDR ranges, and FQDNs for security policiesclient.address_group
- Static or dynamic collections of address objectsclient.application
- Custom application definitions and signaturesclient.application_filter
- Filters for identifying applications by characteristicsclient.application_group
- Logical groups of applications for policy applicationclient.dynamic_user_group
- User groups with dynamic membership criteriaclient.external_dynamic_list
- Externally managed lists of IPs, URLs, or domainsclient.hip_object
- Host information profile match criteriaclient.hip_profile
- Endpoint security compliance profilesclient.http_server_profile
- HTTP server configurations for logging and monitoringclient.log_forwarding_profile
- Configurations for forwarding logs to external systemsclient.quarantined_device
- Management of devices blocked from network accessclient.region
- Geographic regions for policy controlclient.schedule
- Time-based policies and access controlclient.service
- Protocol and port definitions for network servicesclient.service_group
- Collections of services for simplified policy managementclient.syslog_server_profile
- Syslog server configurations for centralized loggingclient.tag
- Resource classification and organization labels
Network
client.ike_crypto_profile
- IKE crypto profiles for VPN tunnelsclient.ike_gateway
- IKE gateway configurations for VPN tunnel endpointsclient.ipsec_crypto_profile
- IPsec crypto profiles for VPN tunnel encryptionclient.nat_rule
- Network address translation policies for traffic routingclient.security_zone
- Security zones for network segmentation
Deployment
client.bandwidth_allocation
- Bandwidth allocation settings for regions and service nodesclient.internal_dns_server
- DNS server configurations for domain resolutionclient.network_location
- Geographic network locations for service connectivityclient.remote_network
- Secure branch and remote site connectivity configurationsclient.service_connection
- Service connections to cloud service providers
Security
client.security_rule
- Core security policies controlling network trafficclient.anti_spyware_profile
- Protection against spyware, C2 traffic, and data exfiltrationclient.decryption_profile
- SSL/TLS traffic inspection configurationsclient.dns_security_profile
- Protection against DNS-based threats and tunnelingclient.url_category
- Custom URL categorization for web filteringclient.vulnerability_protection_profile
- Defense against known CVEs and exploit attemptsclient.wildfire_antivirus_profile
- Cloud-based malware analysis and zero-day protection
Core Methods
HTTP Methods
Makes a GET request to the specified endpoint, automatically handling token refresh.
Makes a POST request to the specified endpoint, automatically handling token refresh.
Makes a PUT request to the specified endpoint, automatically handling token refresh.
Makes a DELETE request to the specified endpoint, automatically handling token refresh.
Job Management Methods
self,
limit: int = 100,
offset: int = 0,
parent_id: Optional[str] = None
) -> JobListResponse
Lists jobs with pagination support and optional parent ID filtering. When parent_id is provided, returns only child jobs of the specified parent job.
Gets the status of a specific job.
self,
job_id: str,
timeout: int = 300,
poll_interval: int = 10
) -> Optional[JobStatusResponse]
Waits for a job to complete with configurable timeout and polling interval.
Configuration Management Methods
self,
folders: List[str],
description: str,
admin: Optional[List[str]] = None,
sync: bool = False,
timeout: int = 300,
) -> CandidatePushResponseModel
Commits configuration changes to SCM with options for synchronous waiting and custom timeout.
Usage Examples
Client Initialization
# Initialize client with basic configurationclient = Scm(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id",
# Optional parameters:
# api_base_url="https://api.custom-domain.com", # Custom API endpoint
# token_url="https://auth.custom-domain.com/oauth2/token", # Custom token endpoint
# log_level="DEBUG" # Change logging level
)
Using the Unified Client Interface
"name": "test-address",
"ip_netmask": "192.168.1.0/24",
"description": "Test network address",
"folder": "Texas"
}
new_address = client.address.create(address_data)
print(f"Created address: {new_address.name} with ID: {new_address.id}")
# List tagstags = client.tag.list(folder="Texas")
for tag in tags:
print(f"Tag: {tag.name}, Color: {tag.color}")
# Create a security rulerule_data = {
"name": "allow-internal",
"folder": "Texas",
"source": {"address": ["test-address"]},
"destination": {"address": ["any"]},
"application": ["web-browsing"],
"service": ["application-default"],
"action": "allow"
}
new_rule = client.security_rule.create(rule_data)
print(f"Created rule: {new_rule.name}")
# Commit changesresult = client.commit(
folders=["Texas"],
description="Added test configuration",
sync=True
)
print(f"Commit job ID: {result.job_id}")
Making Raw API Requests
For endpoints not yet covered by dedicated service classes:
endpoint="/config/objects/v1/addresses",
params={"folder": "Texas", "limit": 100}
)
# Create new objectresponse = client.post(
endpoint="/config/objects/v1/addresses",
json={
"name": "test-address",
"ip_netmask": "192.168.1.0/24",
"folder": "Texas"
}
)
Job Management
# Get child jobs of a specific jobchild_jobs = client.list_jobs(parent_id="parent-job-id")
# Wait for job completionstatus = client.wait_for_job("job-id", timeout=600)
Committing Changes
folders=["Texas"],
admin=["all"],
description="Update network configuration",
sync=True,
timeout=300
)
print(f"Commit job ID: {result.job_id}")
# Check commit statusstatus = client.get_job_status(result.job_id)
print(f"Status: {status.data[0].status_str}")
ScmClient Alias
Starting with version 0.3.14, the SDK also provides an ScmClient
class as an alias for Scm
. This class offers the exact
same functionality but with a more explicit name that better describes its purpose:
# Use ScmClient instead of Scm (identical functionality)client = ScmClient(
client_id="your_client_id",
client_secret="your_client_secret",
tsg_id="your_tsg_id",
# Optional parameters:
# token_url="https://custom.auth.server.com/oauth2/token"
)
Error Handling
try:
result = client.commit(
folders=["Texas"],
admin=["automation@scm-tenant.example.com"],
description="Update configuration",
sync=True
)
except AuthenticationError as e:
print(f"Authentication failed: {e.message}")
except TimeoutError as e:
print(f"Operation timed out: {str(e)}")
except APIError as e:
print(f"API error: {str(e)}")
Best Practices
-
Use the Unified Client Interface
- Leverage the attribute-based access for a cleaner code structure
- Avoid creating separate service instances
- Utilize a single client instance for all operations
-
Client Reuse
- Create a single client instance and reuse it
- Avoid creating multiple client instances
-
Error Handling
- Always wrap API calls in try-except blocks
- Handle specific exceptions before generic ones
- Log error details for troubleshooting
-
Job Management
- Use sync=True for simpler workflows when waiting for job completion
- Set appropriate timeouts based on operation complexity
- Monitor child jobs for complex operations
-
Logging
- Use DEBUG level for development and troubleshooting
- Use ERROR level for production environments