HFortix - Python SDK for Fortinet products (FortiOS, FortiManager, FortiAnalyzer)
Project description
HFortix - Fortinet Python SDK
Python client library for Fortinet products including FortiOS, FortiManager, and FortiAnalyzer.
๐ฏ Current Status
FortiOS 7.6.5 Coverage (December 16, 2025):
- CMDB API: 15 of 40 categories (38% coverage) - 74+ endpoints ๐ท Beta
- Log API: 5 of 5 categories (100% coverage) - 42 methods ๐ท Beta
- Service API: 3 of 3 categories (100% coverage) - 21 methods ๐ท Beta
- Monitor API: Not yet implemented (0 of 28 categories) โธ๏ธ
Latest Features (v0.3.9):
- โจ raw_json Parameter: All 45+ API methods now support
raw_json=Truefor full response access- Default: Returns just the results data
- With
raw_json=True: Returns complete response with status codes, metadata - Example:
fgt.api.cmdb.firewall.address.get('obj1', raw_json=True)
- โจ Logging System: Global and per-instance logging control
- Global:
hfortix.set_log_level('DEBUG'|'INFO'|'WARNING'|'ERROR'|'OFF') - Per-instance:
FortiOS(debug='info') - Automatic sensitive data sanitization (tokens, passwords)
- Request/response logging with timing information
- Global:
- โ Code Quality: 100% PEP 8 compliance (black + isort + flake8)
- โ Bug Fixes: Fixed undefined variables, certificate helpers, DoS policy bugs
- โ Comprehensive Tests: 159 test files covering all endpoints
Previous Releases:
- v0.3.8: Dual-pattern interface for all create/update methods
- v0.3.7: Packaging and layout improvements
- v0.3.6: Hidden internal CRUD methods for cleaner autocomplete
- v0.3.5: Enhanced IDE autocomplete with PEP 561 type hints
- v0.3.4: Unified import syntax documentation
- v0.3.0: Firewall endpoints (28 total: 11 flat + 17 nested)
- firewall.wildcard-fqdn (custom, group)
๐ฏ Features
- Unified Package: Import all Fortinet products from a single package
- Enhanced IDE Support: Full type hints with PEP 561 compliance for excellent autocomplete
- Modular Architecture: Each product module can be used independently
- PyPI Installation:
pip install hfortix- simple and straightforward - Comprehensive Exception Handling: 387+ FortiOS error codes with detailed descriptions
- Type-Safe: Proper exception hierarchy and error handling
- Simplified APIs: Auto-conversion for common patterns (e.g., address group members)
- Well-Documented: Extensive API documentation and examples
- Modern Python: Type hints, PEP 585 compliance, Python 3.8+
๐ฆ Available Modules
| Module | Status | Description |
|---|---|---|
| FortiOS | โ Active | FortiGate firewall management API |
| FortiManager | โธ๏ธ Planned | Centralized management for FortiGate devices |
| FortiAnalyzer | โธ๏ธ Planned | Log analysis and reporting platform |
๐ Installation
From PyPI (Recommended)
pip install hfortix
๐ Quick Start
Basic Usage
from hfortix import FortiOS
# Initialize with API token (recommended)
fgt = FortiOS(
host='192.168.1.99',
token='your-api-token',
verify=False # Use True in production with valid SSL cert
)
# List firewall addresses
addresses = fgt.api.cmdb.firewall.address.list()
print(f"Found {len(addresses['results'])} addresses")
# Create a new address
result = fgt.api.cmdb.firewall.address.create(
name='web-server',
subnet='192.168.10.50/32',
comment='Production web server'
)
Raw JSON Response โจ
All API methods support raw_json parameter for full response access:
# Default behavior - returns just the results
addresses = fgt.api.cmdb.firewall.address.list()
print(addresses) # ['obj1', 'obj2', 'obj3']
# With raw_json=True - returns complete API response
response = fgt.api.cmdb.firewall.address.list(raw_json=True)
print(response['http_status']) # 200
print(response['status']) # 'success'
print(response['results']) # ['obj1', 'obj2', 'obj3']
print(response['serial']) # 'FGT60FTK19000001'
print(response['version']) # 'v7.6.5'
# Useful for error checking
result = fgt.api.cmdb.firewall.address.get('web-server', raw_json=True)
if result['http_status'] == 200:
print(f"Object found: {result['results']}")
else:
print(f"Error: {result.get('error', 'Unknown error')}")
Available on: All 45+ API methods (100% coverage)
Logging Control โจ
Control logging output globally or per-instance:
import hfortix
from hfortix import FortiOS
# Enable detailed logging globally for all instances
hfortix.set_log_level('DEBUG') # Very verbose - all requests/responses
hfortix.set_log_level('INFO') # Normal - request summaries
hfortix.set_log_level('WARNING') # Quiet - only warnings (default)
hfortix.set_log_level('ERROR') # Silent - only errors
hfortix.set_log_level('OFF') # No logging output
# Or enable logging for a specific instance
fgt = FortiOS('192.168.1.99', token='your-token', debug='info')
# Automatic sensitive data sanitization
# Tokens, passwords, and API keys are automatically masked in logs
Features:
- 5 log levels (DEBUG, INFO, WARNING, ERROR, OFF)
- Automatic sensitive data sanitization
- Request/response logging with timing
- Hierarchical loggers for fine-grained control
Dual-Pattern Interface โจ
HFortix supports flexible dual-pattern syntax - use dictionaries, keywords, or mix both:
# Pattern 1: Dictionary-based (great for templates)
config = {
'name': 'web-server',
'subnet': '192.168.10.50/32',
'comment': 'Production web server'
}
fgt.api.cmdb.firewall.address.create(data_dict=config)
# Pattern 2: Keyword-based (great for readability)
fgt.api.cmdb.firewall.address.create(
name='web-server',
subnet='192.168.10.50/32',
comment='Production web server'
)
# Pattern 3: Mixed (template + overrides)
base_config = load_template('address_template.json')
fgt.api.cmdb.firewall.address.create(
data_dict=base_config,
name=f'server-{site_id}', # Override name
comment=f'Site: {site_name}'
)
Available on: 43 methods across 13 categories (100% coverage)
- All CMDB create/update operations (38 endpoints)
- Service operations (5 methods)
Exception Handling
from hfortix import (
FortiOS,
APIError,
ResourceNotFoundError,
DuplicateEntryError
)
try:
result = fgt.api.cmdb.firewall.address.create(
name='test-address',
subnet='10.0.0.0/24'
)
except DuplicateEntryError as e:
print(f"Address already exists: {e}")
except ResourceNotFoundError as e:
print(f"Resource not found: {e}")
except APIError as e:
print(f"API Error: {e.message}")
print(f"HTTP Status: {e.http_status}")
print(f"Error Code: {e.error_code}")
๐๏ธ Project Structure
fortinet/
โโโ hfortix/ # Main package
โ โโโ __init__.py # Public API exports
โ โโโ exceptions.py # Base exceptions
โ โโโ exceptions_forti.py # FortiOS-specific error codes/helpers
โ โโโ py.typed # PEP 561 marker
โ โโโ FortiOS/
โ โโโ __init__.py
โ โโโ fortios.py # FortiOS client
โ โโโ http_client.py # Internal HTTP client
โ โโโ exceptions.py # FortiOS re-exports
โ โโโ api/
โ โโโ v2/
โ โโโ cmdb/
โ โโโ log/
โ โโโ service/
โ โโโ monitor/ # (placeholder / in progress)
โโโ X/ # Internal notes + script-style test harness (not pytest)
๐ Module Discovery
Check which modules are available:
from hfortix import get_available_modules
modules = get_available_modules()
print(modules)
# {'FortiOS': True, 'FortiManager': False, 'FortiAnalyzer': False}
๐ Examples
FortiOS - Firewall Address Management
from hfortix import FortiOS
fgt = FortiOS(host='192.168.1.99', token='your-token', verify=False)
# List addresses
addresses = fgt.api.cmdb.firewall.address.list()
# Create address
result = fgt.api.cmdb.firewall.address.create(
name='web-server',
subnet='10.0.1.100/32',
comment='Production web server'
)
# Update address
result = fgt.api.cmdb.firewall.address.update(
name='web-server',
comment='Updated comment'
)
# Delete address
result = fgt.api.cmdb.firewall.address.delete(name='web-server')
FortiOS - DoS Protection (NEW!)
# Create IPv4 DoS policy with simplified API
result = fgt.api.cmdb.firewall.dos_policy.create(
policyid=1,
name='protect-web-servers',
interface='port3', # Simple string format
srcaddr=['all'], # Simple list format
dstaddr=['web-servers'],
service=['HTTP', 'HTTPS'],
status='enable',
comments='Protect web farm from DoS attacks'
)
# API automatically converts to FortiGate format:
# interface='port3' โ {'q_origin_key': 'port3'}
# service=['HTTP'] โ [{'name': 'HTTP'}]
# Custom anomaly detection thresholds
result = fgt.api.cmdb.firewall.dos_policy.create(
policyid=2,
name='strict-dos-policy',
interface='wan1',
srcaddr=['all'],
dstaddr=['all'],
service=['ALL'],
anomaly=[
{'name': 'tcp_syn_flood', 'threshold': 500, 'action': 'block'},
{'name': 'udp_flood', 'threshold': 1000, 'action': 'block'}
]
)
FortiOS - Reverse Proxy/WAF (NEW!)
# Create access proxy (requires VIP with type='access-proxy')
result = fgt.api.cmdb.firewall.access_proxy.create(
name='web-proxy',
vip='web-vip', # VIP must be type='access-proxy'
auth_portal='enable',
log_blocked_traffic='enable',
http_supported_max_version='2.0',
svr_pool_multiplex='enable'
)
# Create virtual host with simplified API
result = fgt.api.cmdb.firewall.access_proxy_virtual_host.create(
name='api-vhost',
host='*.api.example.com',
host_type='wildcard',
ssl_certificate='Fortinet_Factory' # String auto-converts to list
)
# API automatically converts:
# ssl_certificate='cert' โ [{'name': 'cert'}]
FortiOS - Address & Address Group Management (NEW!)
# Create IPv4 address (subnet)
result = fgt.api.cmdb.firewall.address.create(
name='internal-net',
type='ipmask',
subnet='192.168.1.0/24',
comment='Internal network'
)
# Create IPv4 address (IP range)
result = fgt.api.cmdb.firewall.address.create(
name='dhcp-range',
type='iprange',
start_ip='192.168.1.100',
end_ip='192.168.1.200'
)
# Create IPv4 address (FQDN)
result = fgt.api.cmdb.firewall.address.create(
name='google-dns',
type='fqdn',
fqdn='dns.google.com'
)
# Create IPv6 address
result = fgt.api.cmdb.firewall.address6.create(
name='ipv6-internal',
type='ipprefix',
ip6='2001:db8::/32',
comment='IPv6 internal network'
)
# Create address group with simplified API
result = fgt.api.cmdb.firewall.addrgrp.create(
name='internal-networks',
member=['subnet1', 'subnet2', 'subnet3'], # Simple string list!
comment='All internal networks'
)
# API automatically converts:
# member=['addr1', 'addr2'] โ [{'name': 'addr1'}, {'name': 'addr2'}]
# Create IPv6 address group
result = fgt.api.cmdb.firewall.addrgrp6.create(
name='ipv6-internal-networks',
member=['ipv6-subnet1', 'ipv6-subnet2'],
comment='All internal IPv6 networks'
)
# Create IPv6 address template
result = fgt.api.cmdb.firewall.address6_template.create(
name='ipv6-subnet-template',
ip6='2001:db8::/32',
subnet_segment_count=2,
comment='IPv6 subnet template'
)
FortiOS - Schedule Management
# Create recurring schedule
result = fgt.api.cmdb.firewall.schedule.recurring.create(
name='business-hours',
day=['monday', 'tuesday', 'wednesday', 'thursday', 'friday'],
start='08:00',
end='18:00'
)
# Create one-time schedule
from datetime import datetime, timedelta
tomorrow = datetime.now() + timedelta(days=1)
start = f"09:00 {tomorrow.strftime('%Y/%m/%d')}"
end = f"17:00 {tomorrow.strftime('%Y/%m/%d')}"
result = fgt.api.cmdb.firewall.schedule.onetime.create(
name='maintenance-window',
start=start,
end=end,
color=5
)
Exception Hierarchy
Exception
โโโ FortinetError (base)
โโโ AuthenticationError
โโโ AuthorizationError
โโโ APIError
โโโ ResourceNotFoundError (404)
โโโ BadRequestError (400)
โโโ MethodNotAllowedError (405)
โโโ RateLimitError (429)
โโโ ServerError (500)
โโโ DuplicateEntryError (-5, -15, -100)
โโโ EntryInUseError (-23, -94, -95)
โโโ InvalidValueError (-651, -1, -50)
โโโ PermissionDeniedError (-14, -37)
๐งช Testing
Each module includes comprehensive tests:
# This repo includes script-style integration checks under X/tests (requires FortiGate access).
# They are not intended for pytest collection.
๐ Version
Current version: 0.3.8
from hfortix import get_version
print(get_version())
๐ค Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests
- Submit a pull request
๐ License
MIT
๐ Links
๐ก Tips
- Use API Tokens: Only token-based authentication is supported for FortiOS REST API
- Error Handling: Always catch specific exceptions for better error handling
- Verify SSL: Set
verify=Truein production (requires valid certificates) - Rate Limiting: Be aware of API rate limits (HTTP 429 errors)
โ๏ธ Configuration
Environment Variables
export FGT_HOST="192.168.1.99"
export FGT_TOKEN="your-api-token"
export FGT_VERIFY_SSL="false"
Using .env File
from dotenv import load_dotenv
import os
load_dotenv()
fgt = FortiOS(
host=os.getenv('FGT_HOST'),
token=os.getenv('FGT_TOKEN'),
verify=os.getenv('FGT_VERIFY_SSL', 'false').lower() == 'true'
)
๐ฏ Roadmap
- [๐ง] FortiOS API implementation (In Development)
- Exception handling system (387 error codes)
- Base client architecture
- [๐ท] CMDB endpoints (Beta - partial coverage)
- Firewall (address, policy, service, etc.)
- System (interface, admin, global, etc.)
- Router (static, policy, etc.)
- VPN (IPsec, SSL, etc.)
- [๐ท] Service endpoints (Beta)
- Sniffer, Security Rating, etc.
- [๐ท] Log endpoints (Beta)
- Traffic, Event, Virus, etc.
- Monitor endpoints (Not Started)
- Complete API coverage
- Modular package architecture
- FortiManager module (Not Started)
- FortiAnalyzer module (Not Started)
- PyPI package publication
- Async support
- CLI tool
๐ค Author
Herman W. Jacobsen
- Email: herman@wjacobsen.fo
- LinkedIn: linkedin.com/in/hermanwjacobsen
- GitHub: @hermanwjacobsen
Built 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
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-0.3.10.tar.gz.
File metadata
- Download URL: hfortix-0.3.10.tar.gz
- Upload date:
- Size: 236.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d8275bcd74e4a61568008dea29238f8b446d0cba863b9bdfb14a05678e75d8e
|
|
| MD5 |
76beaa712d5475e3265a7ee57211ff0d
|
|
| BLAKE2b-256 |
8b5cdd7ea7118e5c708e8ac2d05d0d406d79f61c9a8a1947acb8bd169c171f7b
|
File details
Details for the file hfortix-0.3.10-py3-none-any.whl.
File metadata
- Download URL: hfortix-0.3.10-py3-none-any.whl
- Upload date:
- Size: 437.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e3486961a2a23c97fdaa2da017e4ce143e31c08a771b0feb4e7d4b54cffa71c4
|
|
| MD5 |
68600a531f4e9f343ad87d1ee7101fbc
|
|
| BLAKE2b-256 |
d8243725a157de8edacd6733fb44c53e19b9c444735506c4609318b9ab593088
|