hfortix-fortiztp
Python SDK for the FortiZTP Cloud API v2.0 — zero-touch provisioning for FortiGate, FortiAP, FortiSwitch, and FortiExtender devices.
Part of the hfortix SDK family, built on the shared hfortix-core HTTP foundation (retries, rate limiting, circuit breaker, audit logging).
Features
- OAuth 2.0 authentication — auto-login with FortiCloud API credentials,
pre-obtained tokens, or a shared
CloudSession - Full type safety — type hints with
Literaltypes and bundled.pyistubs (PEP 561) for IDE autocomplete - Device lifecycle — list, inspect, provision/unprovision (single or bulk)
- Script management — pre-run CLI script metadata and content
- FortiManager integration — manage FortiManager connection settings
- HTTP metadata — status codes, response times, and raw data on every response
- Rate limit tracking — monitor usage against FortiZTP's 2,000 calls/hour limit
Installation
pip install hfortix-fortiztp
Authentication
Three options:
from hfortix_fortiztp import FortiZTP
# 1. FortiCloud IAM API credentials (auto-login)
client = FortiZTP(api_id="your_api_id", password="your_password")
# 2. Pre-obtained OAuth token
client = FortiZTP(oauth_token="your_oauth_token")
# 3. Shared CloudSession (recommended when also using FortiCare)
from hfortix_core.session import CloudSession
from hfortix_forticare import FortiCare
with CloudSession(api_id="your_api_id", password="your_password") as session:
fcc = FortiCare(session=session) # uses client_id "assetmanagement"
fztp = FortiZTP(session=session) # uses client_id "fortiztp"
# Both share one session; each gets its own OAuth token
Quick Start
from hfortix_fortiztp import FortiZTP
client = FortiZTP(api_id="your_api_id", password="your_password")
# List devices, optionally filtered
response = client.devices.list(provision_status="provisioned")
print(f"Total devices: {response.total}")
for device in response:
print(f"{device.deviceSN}: {device.provisionStatus}")
# Get a single device by serial number
device = client.devices.get(device_sn="FGT60FTK19000001")
print(f"Type: {device.deviceType}, status: {device.provisionStatus}")
# Provision a single device to FortiManager
client.devices.put(
device_sn="FGT60FTK19000001",
device_type="FortiGate",
provision_status="provisioned",
provision_target="FortiManager",
forti_manager_oid=12345,
)
# Bulk provision/unprovision (wire-format dicts)
client.devices.put_bulk(
devices=[
{
"deviceSN": "FGT60FTK19000001",
"deviceType": "FortiGate",
"provisionStatus": "provisioned",
"provisionTarget": "FortiManager",
},
]
)
client.logout()
API Navigation
client.<category> is an alias for client.api.<category> — both work.
client.devices.list(provision_status=..., device_type=..., device_sn=..., use_cache=...)
client.devices.get(device_sn=...) # single device (lists all if omitted)
client.devices.put(device_sn=..., device_type=..., provision_status=..., ...)
client.devices.put_bulk(devices=[...]) # bulk provision/unprovision
client.devices.regions.firmwareprofiles.get(device_sn=..., region=...)
client.scripts.scripts_list()
client.scripts.scripts_get(oid=123)
client.scripts.scripts_post(oid=123, name="script1")
client.scripts.scripts_put(oid=123, name="script1-updated")
client.scripts.scripts_delete(oid=123)
client.scripts.scripts_get_content(oid=123)
client.scripts.scripts_put_content(oid=123)
client.fortimanagers.fortimanagers_list()
client.fortimanagers.fortimanagers_get(oid=789)
client.fortimanagers.fortimanagers_post(sn="FMG-VMTM23010656", ip="192.168.223.20")
client.fortimanagers.fortimanagers_put(oid=789, sn="FMG-VMTM23010656", ip="192.168.223.20")
client.fortimanagers.fortimanagers_delete(oid=789)
client.system.system_get() # service status
Every call returns a FortiZTPResponse with attribute/dict access to the
payload plus .http_status_code, .response_time, .raw, and
.request_info metadata.
Rate Limit Tracking
FortiZTP enforces 2,000 calls/hour. The SDK can track your usage
(monitoring only — enforcement is opt-in via rate_limit=True):
client = FortiZTP(
api_id="...",
password="...",
rate_limit_calls_per_hour=2000,
)
status = client.get_rate_limit_status()
print(f"Calls last hour: {status['calls_last_hour']}")
Documentation
- Package docs: https://hfortix.readthedocs.io
- FortiZTP Cloud API reference: https://fndn.fortinet.net/ (Fortinet Developer Network)
- Full IDE autocomplete via bundled
.pyistubs
Requirements
- Python 3.9+
- hfortix-core >= 0.5.161
- httpx >= 0.24.0
Related Packages
- hfortix-core — Core HTTP client and utilities
- hfortix-fortios — FortiOS REST API
- hfortix-forticare — FortiCare Asset Management API
- hfortix — Meta package
License
MIT License — see LICENSE.
Support
- GitHub Issues: https://github.com/hermanwjacobsen/hfortix-fortiztp/issues
- Documentation: https://hfortix.readthedocs.io
Metadata
Release files for hfortix-fortiztp 0.5.164
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| hfortix_fortiztp-0.5.164.tar.gz | 20.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| hfortix_fortiztp-0.5.164-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.2 kB
Release files / hfortix_fortiztp-0.5.164.tar.gz
| Download URL | hfortix_fortiztp-0.5.164.tar.gz |
|---|---|
| Size | 20.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
57fc7e1291ceae972f4ab83634cd5b601a8919be31e80c66d8747aab56c697bc
|
|
BLAKE2b-256 checksum How to use checksums |
2e7b177259818a8b3ceb9e4fd12bd72abc0c7bcf75b0b68c890c38c133e514fd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / hfortix_fortiztp-0.5.164-py3-none-any.whl
| Download URL | hfortix_fortiztp-0.5.164-py3-none-any.whl |
|---|---|
| Size | 28.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f753f4b4a1c861d5e6f6660924784734cfcb9ef4d75469bfead4182238e0c349
|
|
BLAKE2b-256 checksum How to use checksums |
8100a5aaf22bab46673f6f975295a786287be87feaf0e82fbb83951f87529dfc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|