Skip to main content

Type-safe Python SDK for FortiGate firewall automation and FortiOS REST API - 1,348+ endpoints with async support and complete type safety

Project description

HFortix - FortiGate & FortiOS Automation Library

Type-safe Python SDK for FortiGate firewall automation, FortiOS REST API client, and FortiManager integration

Automate FortiGate configuration, monitoring, and management with a modern Python library featuring complete type safety, async support, and 1,348+ FortiOS API endpoints.

PyPI version Python 3.10+ Documentation Downloads Type Hints Async Support Typing: Typed

Quick Start

pip install hfortix-fortios
from hfortix_fortios import FortiOS

# Connect to FortiGate
fgt = FortiOS(host="192.168.1.99", token="your-api-token")

# Get system status (Monitor endpoint - use dict access for untyped fields)
status = fgt.api.monitor.system.status.get()
print(f"Hostname: {status['hostname']}, Model: {status['model']}")

# Create firewall address
fgt.api.cmdb.firewall.address.post(
    name="webserver",
    subnet="10.0.1.100 255.255.255.255",
    comment="Production web server"
)

# Query with filters
addresses = fgt.api.cmdb.firewall.address.get(
    filter="subnet==10.0.0.0/8"
)

# Close connection
fgt.close()

Features

✅ Complete API Coverage

  • 1,348 FortiOS 7.6.5 endpoints - All CMDB, Monitor, Log, and Service endpoints
  • FortiManager JSON-RPC proxy - Manage multiple devices through FortiManager
  • FortiAnalyzer (coming soon)

✅ Type Safety & IDE Support

  • 100% type coverage for CMDB endpoints - Full autocomplete and validation
  • Partial coverage for Monitor/Log endpoints - Some response fields documented
  • .pyi stub files for excellent IDE integration
  • Pydantic validation for request payloads

✅ Flexible Response Access

# FortiObject - Multiple access methods
addr = fgt.api.cmdb.firewall.address.get(name="server1")

# Attribute access (recommended)
print(addr.subnet)  # Full autocomplete ✅

# Dictionary access
print(addr['subnet'])  # Also works

# Convert to dict/JSON
print(addr.dict)      # Dictionary representation
print(addr.json)      # Pretty-printed JSON string
print(addr.raw)       # Full API envelope with metadata

# Query by mkey returns SINGLE object (not list)
addr = fgt.api.cmdb.firewall.address.get(name="server1")
print(addr.subnet)  # Direct access, no need for addr[0]

# Nested objects fully supported
group = fgt.api.cmdb.firewall.service.group.get(name="MyGroup")
for member in group.member:
    print(member.name)  # FortiObjects all the way down

Note: Monitor and Log endpoints have incomplete response field types due to FortiOS API schema limitations. Attribute access (e.g., status.hostname) works at runtime but may show type errors in your IDE. Use dictionary access (status['hostname']) to avoid IDE warnings, or use .json/.raw to inspect the full response. Field names match FNDN documentation with hyphens (-) converted to underscores (_).

✅ Batch Transactions (FortiOS 6.4.0+)

# Atomic configuration changes with automatic commit/rollback
with fgt.transaction() as txn:
    # All changes in this block are atomic
    fgt.api.cmdb.system.interface.post({...})
    fgt.api.cmdb.firewall.address.post({...})
    fgt.api.cmdb.firewall.policy.post({...})
    # Auto-commits on success, auto-aborts on exception

# Decorator pattern for reusable transactional functions
@fgt.transactional(timeout=120)
def setup_infrastructure():
    fgt.api.cmdb.system.interface.post({...})
    fgt.api.cmdb.firewall.address.post({...})
    return {"status": "success"}

setup_infrastructure()  # Runs in transaction

# Manual control for complex scenarios
with fgt.transaction(auto_commit=False) as txn:
    fgt.api.cmdb.firewall.policy.post({...})
    if validation_passes():
        txn.commit()  # Apply changes
    else:
        txn.rollback()  # Undo everything

# See docs/fortios/TRANSACTIONS.md for complete guide

✅ API Request Inspection

# See exactly what request was made
result = fgt.api.cmdb.firewall.policy.get(filter='srcaddr==internal')
print(result.http_api_request)
# {
#     'method': 'GET',
#     'url': 'https://192.168.1.99/api/v2/cmdb/firewall/policy',
#     'params': {'filter': 'srcaddr==internal', 'vdom': 'root'},
#     'data': None,
#     'timestamp': 1706889600.123
# }

# For FortiManager proxy, use fmg_api_request (alias for http_api_request)
result = fmg.devices['FGT-01'].api.cmdb.firewall.policy.get()
print(result.fmg_api_request)  # Shows FMG proxy request details

# Use cases: debugging, audit logging, troubleshooting
# See docs/fortios/API_REQUEST_INSPECTION.md for complete guide

✅ Modern Python Features

  • Async/await support for concurrent operations
  • Synchronous API for simple scripts
  • Context managers for automatic cleanup
  • Type hints throughout
  • Python 3.10+ with modern syntax

✅ Production Ready

  • Comprehensive error handling with detailed exceptions
  • Audit logging with pluggable handlers (Kafka, webhooks, databases)
  • Rate limiting and exponential backoff retry
  • Circuit breaker pattern for resilience
  • Request/response debugging tools

✅ Comprehensive Testing

  • 1,447 schema validator tests - 100% coverage of all 1,348 endpoints (offline, ~5s execution)
  • 80+ live integration tests - Real API testing with FortiGate/FortiManager
  • Unit tests - HTTP client, response processing, error handling
  • CI/CD ready - Fast offline tests for every commit
  • See TESTING.md and .tests/ for details

✅ Developer Experience

  • No string manipulation - everything is a method call
  • IDE autocomplete for all endpoints and parameters
  • Built-in validation catches errors before API calls
  • Extensive documentation with examples
  • Custom wrappers - easily create your own convenience methods

Current Status

⚠️ BETA STATUS
Version 0.5.152 is production-ready but remains in beta until v1.0.0. Breaking changes are possible before v1.0.0, however after v0.5.150 breaking changes are not expected at this time (if any). The SDK is stable and suitable for production use with comprehensive test coverage.

Recommended: Stay on version 0.5.150+ for maximum stability.

Version: 0.5.152 (Released: February 2, 2026)
FortiOS Coverage: 7.6.5 (1,348 endpoints)
Package Size: ~30 MB (with type stubs)
Status: Production Ready ✅

Test Coverage Summary

Comprehensive test suite with 2,566+ test functions across 67 test files:

Category Test Files Test Functions Coverage
Live Endpoint Tests 251 ~1,800+ CMDB (180), Monitor (63), Log (4), Service (4)
Validators & Helpers 40 ~650+ 75+ utility functions tested
Unit Tests 12 ~100+ Core HTTP, response processing, utils
Integration Tests 3 ~15+ Client lifecycle, hooks, stats
Total 318 2,566+ Extensive coverage across all layers

Test Categories:

  • Endpoint Tests: 251 files testing real API endpoints (CMDB, Monitor, Log, Service)
  • Validator Tests: 40 files covering 75+ validation functions (network, firewall, schedules, SSH/SSL)
  • Unit Tests: Core HTTP client, response processing, error handling, formatting
  • Integration Tests: FortiOS client lifecycle, hooks system, statistics tracking
  • Edge Cases: Special scenarios, list handling, parameter normalization

Key Testing Features:

  • 🔬 Parallel execution support for validator tests (no API calls)
  • 🎯 Sequential execution for endpoint tests (respects API rate limits)
  • 📊 Comprehensive coverage of all 1,348+ FortiOS API endpoints
  • 🛡️ Validation testing for 75+ helper functions and validators
  • 🔄 Integration testing for async/sync clients and proxy functionality

Documentation

📚 Full documentation: https://hfortix.readthedocs.io/

Installation

Standard Installation

pip install hfortix-fortios
# or
pip install hfortix[fortios]  # Meta-package

Alternative Packages

pip install hfortix           # Core only (minimal)
pip install hfortix[all]      # Everything

Minimal Installation (No Stubs)

pip install hfortix-fortios[minimal]
# Smaller package, basic type hints only

Examples

Authentication Options

from hfortix_fortios import FortiOS

# Option 1: API Token (recommended)
fgt = FortiOS(host="192.168.1.99", token="your-api-token")

# Option 2: Username/Password (session-based)
fgt = FortiOS(host="192.168.1.99", username="admin", password="password")

# Option 3: Environment Variables
# Set: FORTIOS_HOST, FORTIOS_TOKEN (or FORTIOS_USERNAME, FORTIOS_PASSWORD)
fgt = FortiOS()  # Automatically loads from environment

# Close connection when done
fgt.close()

Basic Operations

from hfortix_fortios import FortiOS

# Connect to FortiGate
fgt = FortiOS(host="192.168.1.99", token="your-api-token")

# Create
fgt.api.cmdb.firewall.address.post(
    name="server1",
    subnet="10.0.1.50 255.255.255.255"
)

# Read
addr = fgt.api.cmdb.firewall.address.get(name="server1")
print(f"Address: {addr.subnet}")

# Update
fgt.api.cmdb.firewall.address.put(
    name="server1",
    comment="Updated comment"
)

# Delete
fgt.api.cmdb.firewall.address.delete(name="server1")

# Close connection
fgt.close()

FortiManager Proxy

from hfortix_fortios import FortiManagerProxy

# Connect to FortiManager
fmg = FortiManagerProxy(
    host="fortimanager.example.com",
    username="admin",
    password="password"
)

# Login to target device
fmg.login(device="fw-branch-01", adom="production")

# Use same API as FortiOS
addresses = fmg.api.cmdb.firewall.address.get()

# Monitor operations (use dict access for untyped fields)
status = fmg.api.monitor.system.status.get()
print(status['hostname'])

# Logout and close
fmg.logout()
fmg.close()

Error Handling

from hfortix_core.exceptions import (
    APIError,
    ResourceNotFoundError,
    ValidationError
)

try:
    addr = fgt.api.cmdb.firewall.address.get(name="notfound")
except ResourceNotFoundError as e:
    print(f"Address not found: {e}")
except APIError as e:
    print(f"HTTP {e.http_status}: {e.message}")

Advanced Features

# Pydantic model validation
from hfortix_fortios.api.models.cmdb.firewall.address import AddressModel

addr_model = AddressModel(
    name="server1",
    subnet="10.0.1.50 255.255.255.255",
    comment="Validated address"
)
fgt.api.cmdb.firewall.address.post(payload_dict=addr_model.to_fortios_dict())

# Action methods
if fgt.api.cmdb.firewall.address.exists(name="server1"):
    print("Address exists!")

# Move policy
fgt.api.cmdb.firewall.policy.move(
    policyid=10,
    action="before",
    reference_policyid=5
)

# Clone object
fgt.api.cmdb.firewall.address.clone(
    name="original",
    new_name="cloned"
)

# Read-only mode (safe testing)
fgt_readonly = FortiOS(host="...", token="...", read_only=True)
# All write operations will raise exceptions

# Track operations (audit logging)
fgt_tracked = FortiOS(host="...", token="...", track_operations=True)
operations = fgt_tracked.get_operations()

API Coverage

Category Endpoints Endpoint Coverage Response Field Types
CMDB (Configuration) 561 ✅ 100% ✅ 100% autocomplete
Monitor (Status/Stats) 490 ✅ 100% ⚠️ Partial autocomplete
Log (Query Logs) 286 ✅ 100% ⚠️ Partial autocomplete
Service (Operations) 11 ✅ 100% ✅ 100% autocomplete
Total 1,348 100% 886 fully typed

All 1,348 endpoints are fully implemented and functional. Response field types indicate IDE autocomplete availability for response fields. CMDB endpoints have complete field documentation, while Monitor/Log have partial coverage due to FortiOS API schema limitations.

Key Capabilities

Type Safety

  • 100% CMDB type coverage - Full IDE autocomplete for all configuration endpoints
  • Partial Monitor/Log coverage - Use dictionary access for undocumented fields
  • Pydantic validation for request payloads
  • Literal types for enum parameters
  • .json and .raw always available for response inspection

Advanced Features

  • Capabilities detection - Query endpoint support at runtime (SUPPORTS_CREATE, SUPPORTS_MOVE, etc.)
  • Action methods - move(), clone(), exists() helpers for common operations
  • Schema introspection - Runtime get_schema() for all endpoints
  • Query parameters - Advanced filtering, sorting, pagination
  • Pydantic models - 1,065+ models for request validation
  • Read-only mode - Safe testing with read_only=True
  • Operation tracking - Audit logging with track_operations=True
  • Custom HTTP clients - Implement IHTTPClient protocol for custom behavior
  • Performance testing - Built-in performance_test() utility

Enterprise Ready

  • Comprehensive error handling with typed exceptions
  • Circuit breaker pattern for resilience
  • Exponential backoff retry logic
  • Rate limiting support
  • Async/await support for concurrency
  • Context managers for automatic cleanup
  • Audit logging with pluggable handlers

Requirements

  • Python 3.10 or higher
  • FortiOS 7.x (tested on 7.6.5)
  • FortiManager 7.x (for proxy features)

Support & Development

Latest Release (v0.5.152)

February 2, 2026

New Features

  • Batch Transactions - Atomic configuration changes with commit/rollback (FortiOS 6.4.0+)

    • Context manager pattern: with fgt.transaction() as txn:
    • Decorator pattern: @fgt.transactional()
    • Manual control: txn.commit(), txn.rollback()
    • Transaction inspection: txn.show(), fgt.list_transactions() (FortiOS 7.4.1+)
    • See TRANSACTIONS.md for complete guide
  • API Request Inspection - Debug and audit API interactions

    • Access via result.http_api_request and result.fmg_api_request
    • Complete request/response details for debugging
    • Audit logging and performance analysis
    • See API_REQUEST_INSPECTION.md for guide

See CHANGELOG.md for complete version history.

Project Structure

hfortix/
├── packages/
│   ├── core/          # hfortix-core (HTTP client, exceptions)
│   ├── fortios/       # hfortix-fortios (FortiOS/FMG client)
│   └── meta/          # hfortix (meta-package)

Contributing

For feature requests or bug reports, please open an issue on GitHub.


Made with ❤️ for the Fortinet community

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

hfortix-0.5.155.tar.gz (71.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hfortix-0.5.155-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file hfortix-0.5.155.tar.gz.

File metadata

  • Download URL: hfortix-0.5.155.tar.gz
  • Upload date:
  • Size: 71.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for hfortix-0.5.155.tar.gz
Algorithm Hash digest
SHA256 7defdb1d4f29a5caa7d002e481c7691eb1023538902569069de6ed6707e2d94f
MD5 bc72430bac76e300b56bba65c80045f2
BLAKE2b-256 e59f41582d14f1cec01c9761c300903747695aa55f1dba6c7005679a97f0a70b

See more details on using hashes here.

File details

Details for the file hfortix-0.5.155-py3-none-any.whl.

File metadata

  • Download URL: hfortix-0.5.155-py3-none-any.whl
  • Upload date:
  • Size: 9.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for hfortix-0.5.155-py3-none-any.whl
Algorithm Hash digest
SHA256 2952333c4e778fcffe5bf9246f0dc124f8a99675f18709609b958c792d322426
MD5 8f9b3863e30cd3512b4816c58638682b
BLAKE2b-256 bfc395f4543e5c9648380d19843395443cdfdbeb0fdc7d0cb150d46a1cf3667a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page