FortiZTP Cloud API Client - Device provisioning and management
Project description
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
Project details
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_fortiztp-0.5.164.tar.gz.
File metadata
- Download URL: hfortix_fortiztp-0.5.164.tar.gz
- Upload date:
- Size: 20.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57fc7e1291ceae972f4ab83634cd5b601a8919be31e80c66d8747aab56c697bc
|
|
| MD5 |
cfdd0c0b71e6a7da0e706326a9b527ef
|
|
| BLAKE2b-256 |
2e7b177259818a8b3ceb9e4fd12bd72abc0c7bcf75b0b68c890c38c133e514fd
|
File details
Details for the file hfortix_fortiztp-0.5.164-py3-none-any.whl.
File metadata
- Download URL: hfortix_fortiztp-0.5.164-py3-none-any.whl
- Upload date:
- Size: 28.7 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 |
f753f4b4a1c861d5e6f6660924784734cfcb9ef4d75469bfead4182238e0c349
|
|
| MD5 |
99e0b9e1823a979a86dacb4aba054f7a
|
|
| BLAKE2b-256 |
8100a5aaf22bab46673f6f975295a786287be87feaf0e82fbb83951f87529dfc
|