Filtering, Sorting, and Formatting
Complete guide to querying and filtering FortiOS API results with advanced parameters.
Overview
HFortix supports powerful query capabilities for list operations:
Filtering - Find specific objects using comparison and pattern matching operators
Sorting - Order results by any field in ascending or descending order
Formatting - Return only specific fields to reduce bandwidth and improve performance
Pagination - Retrieve results in manageable chunks using start/count parameters
All query parameters are first-class method parameters with full IDE autocomplete and type checking support.
Note
Advanced filtering, sorting, and formatting features require FortiOS 6.4.2 or later.
Basic filtering with == operator is available in all FortiOS versions.
Quick Examples
from hfortix import FortiOS
fgt = FortiOS(host='192.168.1.99', token='token')
# Simple exact match filter
addresses = fgt.api.cmdb.firewall.address.get(
filter='name==web-server'
)
# Complex filter with AND operator
policies = fgt.api.cmdb.firewall.policy.get(
filter='srcintf==port1&action==accept'
)
# Sort results descending by policy ID
policies = fgt.api.cmdb.firewall.policy.get(
sort='policyid,dsc'
)
# Return only specific fields
addresses = fgt.api.cmdb.firewall.address.get(
format='name|subnet|comment'
)
# Combine all parameters
policies = fgt.api.cmdb.firewall.policy.get(
filter='action==accept&status==enable',
sort='policyid,asc',
format='policyid|name|srcintf|dstintf',
start=0,
count=50
)
Filter Operators
Comparison Operators
Operator |
Description |
Example |
|---|---|---|
|
Exact match (case-sensitive) |
|
|
Not equal to |
|
|
Contains substring |
|
|
Does not contain |
|
|
Less than or equal |
|
|
Less than |
|
|
Greater than or equal |
|
|
Greater than |
|
Logical Operators
Operator |
Description |
Example |
|---|---|---|
|
Logical AND |
|
|
Logical OR |
|
Filter Examples
Exact match:
# Find address object by exact name
address = fgt.api.cmdb.firewall.address.get(
filter='name==web-server'
)
# Find enabled policies with accept action
policies = fgt.api.cmdb.firewall.policy.get(
filter='status==enable&action==accept'
)
Pattern matching:
# Find addresses containing "server" in name
addresses = fgt.api.cmdb.firewall.address.get(
filter='name=@server'
)
# Find addresses NOT containing "test"
addresses = fgt.api.cmdb.firewall.address.get(
filter='name!@test'
)
# Find addresses with comments containing "production"
addresses = fgt.api.cmdb.firewall.address.get(
filter='comment=@production'
)
Inequality filters:
# Find policies NOT disabled
policies = fgt.api.cmdb.firewall.policy.get(
filter='status!=disable'
)
# Find policies NOT in port1
policies = fgt.api.cmdb.firewall.policy.get(
filter='srcintf!=port1'
)
Numeric comparisons:
# Find sessions with timeout >= 3600
sessions = fgt.api.cmdb.firewall.session.get(
filter='timeout>=3600'
)
# Find policies with priority > 5
policies = fgt.api.cmdb.firewall.policy.get(
filter='priority>5'
)
Logical AND (multiple conditions must be true):
The library supports both syntax formats for AND filtering:
# Format 1: Implicit & separator (recommended - most convenient)
# The library automatically normalizes this to FortiOS format
policies = fgt.api.cmdb.firewall.policy.get(
filter='status==enable&srcintf==port1'
)
# Format 2: Explicit &filter= separator (FortiOS native format)
# Both formats produce identical results
policies = fgt.api.cmdb.firewall.policy.get(
filter='status==enable&filter=srcintf==port1'
)
# More examples with implicit syntax
# Addresses in specific subnet range with specific type
addresses = fgt.api.cmdb.firewall.address.get(
filter='subnet=@192.168&type==ipmask'
)
# Three conditions combined
policies = fgt.api.cmdb.firewall.policy.get(
filter='action==accept&status==enable&srcintf==port1'
)
# Multiple exclusions
addresses = fgt.api.cmdb.firewall.address.get(
filter='name=@test&name!@web&name!@ftp'
)
Note: Both
filter='a&b'andfilter='a&filter=b'syntaxes are supported and produce identical results. The library automatically normalizes the filter string internally to work with FortiOS’s native format.
Logical OR (any condition can be true):
# Policies from port1 OR port2
policies = fgt.api.cmdb.firewall.policy.get(
filter='srcintf==port1,srcintf==port2'
)
# Multiple interface matches
policies = fgt.api.cmdb.firewall.policy.get(
filter='srcintf==wan1,srcintf==wan2,srcintf==dmz'
)
Note
Filter Syntax Normalization
The library supports 4 different filter syntax formats for AND operations, automatically normalizing them to FortiOS’s native format. All formats produce identical results:
Implicit & separator (recommended - cleanest):
filter='name=@test&type==ipmask'
Mixed implicit/explicit:
filter='name=@test&filter=type==ipmask'
Explicit with filter= prefix:
filter='filter=name=@test&filter=type==ipmask'
Prefix with implicit & separator:
filter='filter=name=@test&type==ipmask'
All 4 formats are equivalent - use whichever feels most natural for your use case. The library automatically normalizes them internally.
Complete example:
# All of these produce identical results:
addresses = fgt.api.cmdb.firewall.address.get(filter='name=@test&type==ipmask')
addresses = fgt.api.cmdb.firewall.address.get(filter='name=@test&filter=type==ipmask')
addresses = fgt.api.cmdb.firewall.address.get(filter='filter=name=@test&filter=type==ipmask')
addresses = fgt.api.cmdb.firewall.address.get(filter='filter=name=@test&type==ipmask')
## Sorting Results
Use the `sort` parameter to order results by any field.
**Sort syntax:**
- `field` - Sort ascending (default)
- `field,asc` - Sort ascending (explicit)
- `field,dsc` - Sort descending
**Sort examples:**
```python
# Sort by name (ascending, default)
addresses = fgt.api.cmdb.firewall.address.get(
sort='name'
)
# Sort by policy ID descending
policies = fgt.api.cmdb.firewall.policy.get(
sort='policyid,dsc'
)
# Sort by subnet ascending
addresses = fgt.api.cmdb.firewall.address.get(
sort='subnet,asc'
)
# Combine with filter: enabled policies sorted by ID
policies = fgt.api.cmdb.firewall.policy.get(
filter='status==enable',
sort='policyid,asc'
)
Formatting Output
Use the format parameter to return only specific fields. This reduces bandwidth and improves performance.
Format syntax:
field1|field2|field3- Pipe-separated field names
Format examples:
# Return only name and subnet
addresses = fgt.api.cmdb.firewall.address.get(
format='name|subnet'
)
# Return minimal policy information
policies = fgt.api.cmdb.firewall.policy.get(
format='policyid|name|action|status'
)
# Return only interface names
interfaces = fgt.api.cmdb.system.interface.get(
format='name'
)
# Combine with filter and sort
policies = fgt.api.cmdb.firewall.policy.get(
filter='action==accept',
sort='policyid,dsc',
format='policyid|name|srcintf|dstintf'
)
Note
Formatting is applied by FortiOS before returning results, reducing network transfer size. All filtered fields are still accessible for filtering logic on the FortiOS side.
Pagination
Use start and count parameters to retrieve results in chunks.
Pagination parameters:
start- Zero-based index of first result (default: 0)count- Maximum number of results to return
Note
FortiOS returns all matching results by default (no implicit pagination). Pagination is typically only needed for extremely large datasets (10,000+ objects).
Pagination examples:
# Get first 50 addresses
addresses = fgt.api.cmdb.firewall.address.get(
count=50
)
# Get next 50 addresses (51-100)
addresses = fgt.api.cmdb.firewall.address.get(
start=50,
count=50
)
# Get addresses 101-150
addresses = fgt.api.cmdb.firewall.address.get(
start=100,
count=50
)
# Combine with filtering
policies = fgt.api.cmdb.firewall.policy.get(
filter='status==enable',
start=0,
count=25
)
Complete Examples
Example 1: Filter, Sort, and Format Addresses
# Get production addresses, sorted by name, with minimal fields
addresses = fgt.api.cmdb.firewall.address.get(
filter='comment=@production',
sort='name,asc',
format='name|subnet|comment'
)
for addr in addresses:
print(f"{addr.name}: {addr.subnet}")
Example 2: Find Specific Policies
# Get enabled accept policies from specific interfaces
policies = fgt.api.cmdb.firewall.policy.get(
filter='status==enable&action==accept&(srcintf==port1,srcintf==port2)',
sort='policyid,asc',
format='policyid|name|srcintf|dstintf|action'
)
for policy in policies:
print(f"Policy {policy.policyid}: {policy.name}")
print(f" {policy.srcintf} -> {policy.dstintf}")
Example 3: Paginated Results with All Features
# Get first 25 enabled policies, sorted, with specific fields
policies = fgt.api.cmdb.firewall.policy.get(
filter='status==enable',
sort='policyid,dsc',
format='policyid|name|srcintf|dstintf|action|status',
start=0,
count=25
)
print(f"Retrieved {len(policies)} policies")
for policy in policies:
print(f"{policy.policyid}: {policy.name} ({policy.action})")
Example 4: Search and Filter Addresses
# Find all addresses in 192.168.x.x range, excluding test addresses
addresses = fgt.api.cmdb.firewall.address.get(
filter='subnet=@192.168&comment!@test',
sort='subnet,asc',
format='name|subnet|comment'
)
for addr in addresses:
print(f"{addr.name}: {addr.subnet}")
if hasattr(addr, 'comment'):
print(f" Comment: {addr.comment}")
Best Practices
Performance Optimization
Use format parameter - Return only needed fields to reduce bandwidth
# Good - only retrieve needed fields policies = fgt.api.cmdb.firewall.policy.get( format='policyid|name|status' ) # Avoid - retrieves all fields (larger payload) policies = fgt.api.cmdb.firewall.policy.get()
Filter on FortiOS side - Let FortiOS filter before returning results
# Good - FortiOS filters, returns only matches addresses = fgt.api.cmdb.firewall.address.get( filter='comment=@production' ) # Avoid - retrieves all, filters in Python all_addresses = fgt.api.cmdb.firewall.address.get() prod_addresses = [a for a in all_addresses if 'production' in a.comment]
Use pagination for large datasets - Don’t retrieve 10,000+ objects at once
# Good - retrieve in chunks for page in range(0, 10000, 100): batch = fgt.api.cmdb.firewall.address.get(start=page, count=100) process_batch(batch)
Filter Efficiency
Specific filters are faster - Use exact matches when possible
# Fast - exact match address = fgt.api.cmdb.firewall.address.get(filter='name==web-server') # Slower - pattern matching addresses = fgt.api.cmdb.firewall.address.get(filter='name=@server')
Combine filters efficiently - Put most restrictive filters first
# Better - restrictive filter first policies = fgt.api.cmdb.firewall.policy.get( filter='policyid==100&status==enable' ) # Less efficient - broad filter first policies = fgt.api.cmdb.firewall.policy.get( filter='status==enable&policyid==100' )
Code Clarity
Use descriptive filter strings - Make intent clear
# Clear intent enabled_accept_policies = fgt.api.cmdb.firewall.policy.get( filter='status==enable&action==accept' )
Break complex filters into variables - Improve readability
# Complex filter as variable production_filter = 'comment=@production&status==enable&name!@test' addresses = fgt.api.cmdb.firewall.address.get( filter=production_filter, sort='name,asc', format='name|subnet|comment' )
Version Compatibility
Feature |
FortiOS Version |
Notes |
|---|---|---|
Basic filtering ( |
All versions |
Always available |
Advanced operators |
6.4.2+ |
|
Sorting ( |
6.4.2+ |
All fields supported |
Formatting ( |
6.4.2+ |
Reduces bandwidth |
Pagination |
All versions |
|
Warning
Using advanced operators on FortiOS < 6.4.2 may result in API errors or unexpected behavior. Check your FortiOS version before using advanced filtering features.
Troubleshooting
No Results Returned
Problem: Filter returns empty list when objects exist
Solutions:
Check filter syntax - operators are case-sensitive
# Wrong filter='name=web-server' # Missing second = # Correct filter='name==web-server'
Verify field names match FortiOS schema
# Check object structure first address = fgt.api.cmdb.firewall.address.get(name='test') print(vars(address)) # See all available fields
Check for case-sensitivity in exact matches
# Case-sensitive exact match filter='name==Web-Server' # Won't match 'web-server' # Use contains for case-insensitive filter='name=@server' # Matches 'web-server', 'Web-Server', etc.
Format Parameter Not Working
Problem: All fields returned despite using format parameter
Cause: FortiOS < 6.4.2 or unsupported endpoint
Solution:
Check FortiOS version
Verify endpoint supports formatting
Filter in Python if needed:
all_data = fgt.api.cmdb.firewall.address.get() filtered = [{'name': a.name, 'subnet': a.subnet} for a in all_data]
See Also
API Request Inspection - Debug filter parameters
Performance Guide - Optimize query performance
Firewall Policies - Policy-specific filtering examples