Advanced Patterns

Advanced usage patterns and techniques.

Async Operations

Create the client with mode="async" and await the same endpoint methods you use in sync mode. Concurrency comes from asyncio.gather():

import asyncio
from hfortix_fortios import FortiOS

async def get_all_data(fgt):
    # Concurrent API calls
    addresses, policies, status = await asyncio.gather(
        fgt.api.cmdb.firewall.address.get(),
        fgt.api.cmdb.firewall.policy.get(),
        fgt.api.monitor.system.status.get(),
    )
    return addresses, policies, status

async def main():
    async with FortiOS(
        host='192.168.1.99',
        token='your-token',
        mode='async'
    ) as fgt:
        addresses, policies, status = await get_all_data(fgt)
        print(f"{len(addresses)} addresses, {len(policies)} policies")

asyncio.run(main())

See the Async Usage guide for details.

Bulk Operations

# Create multiple addresses (sync mode)
addresses_to_create = [
    {'name': f'server-{i}', 'subnet': f'10.0.1.{i} 255.255.255.255'}
    for i in range(1, 11)
]

for addr in addresses_to_create:
    fgt.api.cmdb.firewall.address.post(**addr)

In async mode the same loop can run concurrently:

results = await asyncio.gather(*[
    fgt.api.cmdb.firewall.address.post(**addr)
    for addr in addresses_to_create
])

Atomic Changes with Transactions

Group related changes so they commit together or not at all (FortiOS 6.4.0+):

with fgt.transaction() as txn:
    fgt.api.cmdb.firewall.address.post(
        name='app-server',
        subnet='10.0.2.10 255.255.255.255'
    )
    fgt.api.cmdb.firewall.address.post(
        name='db-server',
        subnet='10.0.2.20 255.255.255.255'
    )
    # Commits automatically on clean exit; aborts on exception

See Also