FortiOS SDK - Part of HFortix
Project description
HFortix FortiOS
Python SDK for FortiGate/FortiOS API - Complete, type-safe, production-ready.
⚠️ BETA STATUS - Version 0.5.132 (January 21, 2026)
Status: Production-ready but in beta until v1.0 with comprehensive unit tests.
Overview
Complete Python client for FortiOS 7.6.5 REST API with 100% endpoint coverage (1,348 endpoints), full type safety, and enterprise features. All code is auto-generated from FortiOS API schemas.
Installation
pip install hfortix-fortios
This automatically installs:
hfortix-core- Core utilities and HTTP client
For everything (includes future products):
pip install hfortix[all]
Quick Start
from hfortix_fortios import FortiOS
# Connect to FortiGate
fgt = FortiOS(
host="192.168.1.99",
token="your-api-token",
verify=False
)
# Get system status (Monitor endpoint - use dict access for untyped fields)
status = fgt.api.monitor.system.status.get()
print(f"Hostname: {status['hostname']}")
print(f"Model: {status['model']}")
# Create a firewall address (CMDB endpoint - POST)
fgt.api.cmdb.firewall.address.post(
name="web-server",
subnet="192.168.1.100 255.255.255.255",
comment="Production web server"
)
# Update an existing address (CMDB endpoint - PUT)
fgt.api.cmdb.firewall.address.put(
name="web-server",
subnet="192.168.1.101 255.255.255.255"
)
# Get a specific address (CMDB endpoint - GET)
addr = fgt.api.cmdb.firewall.address.get(name="web-server")
print(f"Address: {addr.name} = {addr.subnet}")
# Delete an address (CMDB endpoint - DELETE)
fgt.api.cmdb.firewall.address.delete(name="web-server")
API Structure
All endpoints follow REST conventions with GET, POST, PUT, DELETE methods:
# CMDB - Configuration Management (full CRUD)
fgt.api.cmdb.firewall.address.get() # List all
fgt.api.cmdb.firewall.address.get(name="x") # Get specific
fgt.api.cmdb.firewall.address.post(...) # Create new
fgt.api.cmdb.firewall.address.put(...) # Update existing
fgt.api.cmdb.firewall.address.delete(name="x") # Delete
# Monitor - Real-time data (mostly GET)
fgt.api.monitor.system.status.get()
fgt.api.monitor.system.resource.usage.get()
fgt.api.monitor.firewall.session.get()
fgt.api.monitor.router.ipv4.get()
# Log - Historical logs (GET)
fgt.api.log.disk.traffic.forward.get(rows=100)
fgt.api.log.disk.event.vpn.get(rows=50)
fgt.api.log.memory.event.system.get()
# Service - System services
fgt.api.service.sniffer.start.post(...)
API Coverage
FortiOS 7.6.5 - 100% Coverage (Schema v1.7.0):
| Category | Endpoints | Description |
|---|---|---|
| CMDB | 561 | Configuration management (firewall, system, VPN, routing, etc.) |
| Monitor | 490 | Real-time monitoring (sessions, stats, resources, etc.) |
| Log | 286 | Log queries (disk, memory, FortiAnalyzer, FortiCloud) |
| Service | 11 | Service operations (sniffer, security rating, system) |
| Total | 1,348 | With 2,129 implementation files |
Key Features
🎯 IDE Autocomplete with Literal Types
Every enum parameter provides instant IDE suggestions:
# ✨ Autocomplete for ALL enum fields
fgt.api.cmdb.firewall.policy.post(
name="allow-web",
srcintf=[{"name": "port1"}],
dstintf=[{"name": "port2"}],
srcaddr=[{"name": "all"}],
dstaddr=[{"name": "web-server"}],
service=[{"name": "HTTP"}, {"name": "HTTPS"}],
action="accept", # 💡 IDE: 'accept', 'deny', 'ipsec'
status="enable", # 💡 IDE: 'enable', 'disable'
nat="enable", # 💡 IDE: 'enable', 'disable'
logtraffic="all", # 💡 IDE: 'all', 'utm', 'disable'
schedule="always"
)
# 🛡️ Type safety catches errors at development time
fgt.api.cmdb.system.interface.post(
name="vlan100",
vdom="root",
mode="static", # 💡 IDE: 'static', 'dhcp', 'pppoe'
type="vlan", # 💡 IDE: 'physical', 'vlan', 'tunnel', ...
role="lan" # 💡 IDE: 'lan', 'wan', 'dmz', 'undefined'
)
🎨 FortiObject Response Wrapper
All methods return FortiObject with clean attribute access:
# Get policies and access fields directly
policies = fgt.api.cmdb.firewall.policy.get()
for policy in policies:
print(f"Policy {policy.policyid}: {policy.name}")
print(f" Action: {policy.action}")
print(f" Status: {policy.status}")
# join() flattens member tables for display
print(f" {policy.join('srcintf')} → {policy.join('dstintf')}")
print(f" {policy.join('srcaddr')} → {policy.join('dstaddr')}")
# Access as dict when needed
policy_dict = policy.to_dict()
# Access raw API envelope
raw = policy.raw # {'http_status': 200, 'status': 'success', 'results': ...}
⚡ Async Support
import asyncio
from hfortix_fortios import FortiOS
async def main():
async with FortiOS(host="...", token="...", mode="async") as fgt:
# All methods support await
addresses = await fgt.api.cmdb.firewall.address.get()
# Concurrent operations
addr, pol, svc = await asyncio.gather(
fgt.api.cmdb.firewall.address.get(),
fgt.api.cmdb.firewall.policy.get(),
fgt.api.cmdb.firewall.service.custom.get()
)
asyncio.run(main())
🔧 Error Handling
from hfortix_core import (
APIError,
ResourceNotFoundError,
DuplicateEntryError,
AuthenticationError,
)
try:
fgt.api.cmdb.firewall.address.post(name="test", subnet="10.0.0.1/32")
except DuplicateEntryError:
print("Address already exists")
except ResourceNotFoundError:
print("Resource not found")
except AuthenticationError:
print("Invalid API token")
except APIError as e:
print(f"API Error: {e.message} (code: {e.error_code})")
🔒 Read-Only Mode & Operation Tracking
# Safe testing - block all write operations
fgt = FortiOS(host="...", token="...", read_only=True)
# Audit logging - track all API calls
fgt = FortiOS(host="...", token="...", track_operations=True)
operations = fgt.get_operations()
🔍 Debugging
# Enable debug logging
fgt = FortiOS(host="...", token="...", debug=True)
# Connection pool monitoring
stats = fgt.connection_stats
print(f"Active: {stats['active_requests']}/{stats['max_connections']}")
# Request inspection
result = fgt.api.cmdb.firewall.address.get()
info = fgt.last_request
print(f"Endpoint: {info['endpoint']}")
print(f"Response time: {info['response_time_ms']}ms")
🔧 Enterprise Features
- Audit Logging: Built-in compliance logging with SIEM integration
- HTTP/2 Support: Connection multiplexing for better performance
- Automatic Retry: Handles transient failures (429, 500, 502, 503, 504)
- Circuit Breaker: Prevents cascade failures with automatic recovery
- Request Tracking: Correlation IDs for distributed tracing
Examples
Firewall Policy Management
# Create a policy
fgt.api.cmdb.firewall.policy.post(
name="Allow-Web",
srcintf=[{"name": "port1"}],
dstintf=[{"name": "port2"}],
srcaddr=[{"name": "all"}],
dstaddr=[{"name": "web-servers"}],
action="accept",
schedule="always",
service=[{"name": "HTTP"}, {"name": "HTTPS"}],
logtraffic="all"
)
# Check if policy exists
if fgt.api.cmdb.firewall.policy.exists(policyid=10):
# Update the policy
fgt.api.cmdb.firewall.policy.put(
policyid=10,
status="disable"
)
Address Group Management
# Create addresses
fgt.api.cmdb.firewall.address.post(
name="subnet1",
subnet="10.0.1.0 255.255.255.0"
)
fgt.api.cmdb.firewall.address.post(
name="subnet2",
subnet="10.0.2.0 255.255.255.0"
)
# Create address group
fgt.api.cmdb.firewall.addrgrp.post(
name="internal-networks",
member=[{"name": "subnet1"}, {"name": "subnet2"}],
comment="All internal networks"
)
VPN Configuration
# Create IPsec Phase 1
fgt.api.cmdb.vpn.ipsec.phase1_interface.post(
name="site-to-site",
type="static",
interface="wan1",
ike_version="2",
peertype="any",
proposal="aes256-sha256",
remote_gw="203.0.113.10",
psksecret="your-pre-shared-key"
)
# Create IPsec Phase 2
fgt.api.cmdb.vpn.ipsec.phase2_interface.post(
name="site-to-site-p2",
phase1name="site-to-site",
proposal="aes256-sha256",
src_subnet="10.0.0.0 255.0.0.0",
dst_subnet="192.168.0.0 255.255.0.0"
)
System Monitoring
# Get system status (use dict access for untyped Monitor fields)
status = fgt.api.monitor.system.status.get()
print(f"Hostname: {status['hostname']}")
print(f"Model: {status['model']} ({status['model_number']})")
# Get resource usage
resources = fgt.api.monitor.system.resource.usage.get()
print(f"CPU: {resources.results['cpu']}%")
print(f"Memory: {resources.results['mem']}%")
# Get active sessions
sessions = fgt.api.monitor.firewall.session.get()
print(f"Total sessions: {len(sessions.results)}")
FortiManager Proxy
Route FortiOS API calls through FortiManager to managed devices:
from hfortix_fortios import FortiManagerProxy
# Connect to FortiManager
fmg = FortiManagerProxy(
host="fortimanager.example.com",
username="admin",
password="password",
adom="root",
verify=False
)
# Get a proxied FortiOS connection to a managed device
fgt = fmg.get_device("fw01")
# Use the same API as direct FortiOS!
addresses = fgt.api.cmdb.firewall.address.get()
for addr in addresses:
print(f"{addr.name}: {addr.subnet}")
# Create, update, delete - all work through the proxy
fgt.api.cmdb.firewall.address.post(
name="Server-01",
subnet="10.0.1.10 255.255.255.255"
)
# Clean up
fmg.logout()
Import Patterns
# Recommended
from hfortix_fortios import FortiOS
from hfortix_fortios import FortiManagerProxy
# Also available
from hfortix import FortiOS
Requirements
- Python 3.10+
- FortiOS 7.0+ (tested with 7.6.5)
- hfortix-core >= 0.5.132
Documentation
License
Proprietary - See LICENSE file
Support
Author
Herman W. Jacobsen
- Email: herman@wjacobsen.fo
- GitHub: @hermanwjacobsen
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hfortix_fortios-0.5.150.tar.gz.
File metadata
- Download URL: hfortix_fortios-0.5.150.tar.gz
- Upload date:
- Size: 6.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95b881343aecfc01a46c59d25789a3027d55158dc32d0dffaa10a30f52503a99
|
|
| MD5 |
55d112630174b44a225754a63a04be84
|
|
| BLAKE2b-256 |
72c49d2c9705cd20cc3ec865b2033b69c54d2b62c20023c935ab1bf75421d52d
|
File details
Details for the file hfortix_fortios-0.5.150-py3-none-any.whl.
File metadata
- Download URL: hfortix_fortios-0.5.150-py3-none-any.whl
- Upload date:
- Size: 12.3 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
99b4b0426c69eb3ead60d9a6646bb60cd0ca5921937578ca75c188c9f86ba681
|
|
| MD5 |
f402e484e20f9aad055f3a47d9440f0e
|
|
| BLAKE2b-256 |
34efa113c5bb1e2347dc5c51ad0b2796057a6f4e8a77964acd1d6972b44dd4b1
|