FortiZTP Cloud API Client - Device provisioning and management
Project description
FortiZTP Package
Python SDK for FortiZTP Cloud API v2.0 - Device provisioning and management for FortiGate, FortiAP, FortiSwitch, and FortiExtender.
Status
✅ FUNCTIONAL - BETA RELEASE
Schema Completion: 100% (18/18 endpoints)
- ✅ Device endpoints: 5/5 complete
- ✅ Script endpoints: 7/7 complete
- ✅ FortiManager endpoints: 5/5 complete
- ✅ System endpoint: 1/1 complete
Code Generation: ✅ Complete - All 18 endpoints auto-generated from schema
Testing: ✅ Live tests passing - GET /v2/devices validated with real API
See dev/SCHEMA_GAPS_ANALYSIS.md for details on missing information.
Overview
This package will provide a fully typed Python SDK for FortiZTP Cloud API with:
- 🔒 OAuth 2.0 Authentication - Automatic token management
- 📝 Full Type Safety - Type hints with Literal types for autocomplete
- 🎯 Specialized Responses - Property access on response objects
- 🔄 Smart Defaults - Sensible defaults for optional parameters
- ⚡ HTTP Metadata - Status codes, response times, raw access
- 🛡️ Error Handling - Comprehensive exception handling
Quick Start
Installation
pip install hfortix-fortiztp
Basic Usage
from hfortix_fortiztp import FortiZTP
# Initialize client with OAuth credentials
client = FortiZTP(
api_id="your_api_id",
password="your_password"
)
# List all devices
devices = client.api.devices.list()
print(f"Found {len(devices.devices)} devices")
# List provisioned devices only
provisioned = client.api.devices.list(provision_status="provisioned")
# Get specific device details
device = client.api.devices.get(device_sn="FGT60FTK19000001")
print(f"Device: {device.deviceType} - Status: {device.provisionStatus}")
# Get system status
status = client.api.system.get()
print(f"System status: {status.serviceStatus}")
API Coverage
Devices API (5 endpoints)
- ✅
list()- List devices with filters (status, type, SN) - ✅
bulk_provision()- Provision/unprovision multiple devices - ✅
get()- Get single device details - ✅
update()- Provision/unprovision single device - ✅
firmware_profiles()- Get firmware profiles by region
Scripts API (7 endpoints)
- ✅
scripts_list()- List all scripts - ✅
scripts_post()- Create new script - ✅
scripts_get()- Get script metadata - ✅
scripts_put()- Update script metadata - ✅
scripts_delete()- Delete script - ✅
scripts_content_get()- Download script content - ✅
scripts_content_put()- Upload script content
FortiManagers API (5 endpoints)
- ✅
fortimanagers_list()- List all FortiManager configs - ✅
fortimanagers_post()- Create FortiManager config - ✅
fortimanagers_get()- Get FortiManager details - ✅
fortimanagers_put()- Update FortiManager config - ✅
fortimanagers_delete()- Delete FortiManager config
System API (1 endpoint)
- ✅
get()- Get system status - Script association
System (1 endpoint)
- Get system status
Planned Usage
Note: This is the intended API design. Code is not yet generated.
Basic Usage
from hfortix import FortiZTP
# Initialize client with OAuth credentials
client = FortiZTP(
client_id="your_client_id",
api_key="your_api_key",
password="your_password"
)
# List all provisioned devices
response = client.v2.devices.list.get(provision_status="provisioned")
# Access response properties
print(f"Total devices: {response.total}")
print(f"Has cache: {response.hasCache}")
for device in response.data:
print(f"{device['deviceSN']}: {device['provisionStatus']}")
# Get specific device
device = client.v2.devices.get.get(device_sn="FGT60D4615067214")
print(f"Device type: {device.deviceType}")
print(f"Status: {device.provisionStatus}")
# Provision a device to FortiManager
client.v2.devices.put.put(
device_sn="FGT60D4615067214",
request_body={
"provisionStatus": "provisioned",
"provisionTarget": "FortiManager",
"provisionTargetOid": 123
}
)
Type Safety with Literals
from typing import Literal
# IDE will autocomplete these values:
DeviceType = Literal["FortiGate", "FortiAP", "FortiSwitch", "FortiExtender"]
ProvisionStatus = Literal["provisioned", "unprovisioned", "hidden", "incomplete"]
ProvisionTarget = Literal["FortiManager", "FortiGateCloud", "FortiEdgeCloud", "ExternalController"]
# Strongly typed parameters
response = client.v2.devices.list.get(
provision_status="provisioned", # Autocomplete!
device_type="FortiGate" # Autocomplete!
)
Script Management
# List all scripts
scripts = client.v2.settings.scripts.list.get()
print(f"Total scripts: {scripts.total}")
# Create new script
new_script = client.v2.settings.scripts.post.post(
request_body={
"name": "Initial Configuration",
}
)
print(f"Created script OID: {new_script.oid}")
# Upload script content
client.v2.settings.scripts.put_content.put(
oid=new_script.oid,
file_path="./scripts/initial_config.conf"
)
# Download script content
content = client.v2.settings.scripts.get_content.get(oid=new_script.oid)
print(content.raw) # Plain text content
FortiManager Configuration
# Add FortiManager
fmg = client.v2.settings.fortimanagers.post.post(
request_body={
"sn": "FMG-VMTM23010656",
"ip": "192.168.223.20",
"scriptOid": 123 # Optional pre-run script
}
)
# HA Setup (comma-separated values)
fmg_ha = client.v2.settings.fortimanagers.post.post(
request_body={
"sn": "FMG-VMTM23010656,FMG-VMTM23010657",
"ip": "192.168.223.20,192.168.223.21",
"scriptOid": 123
}
)
# List all FortiManagers
all_fmgs = client.v2.settings.fortimanagers.list.get()
for fmg in all_fmgs.data:
print(f"{fmg['sn']} at {fmg['ip']}")
HTTP Metadata Access
response = client.v2.devices.get.get(device_sn="FGT60D4615067214")
# HTTP metadata
print(f"Status code: {response.http_status_code}")
print(f"Response time: {response.response_time}s")
# Raw access
raw_dict = response.raw
copy_dict = response.dict()
Error Handling
from hfortix_core.exceptions import (
AuthenticationError,
PermissionDeniedError,
ResourceNotFoundError,
RateLimitError
)
try:
device = client.v2.devices.get.get(device_sn="INVALID_SN")
except ResourceNotFoundError as e:
print(f"Device not found: {e}")
except PermissionDeniedError as e:
print(f"Access denied: {e}")
except RateLimitError as e:
print(f"Rate limit exceeded: {e}")
print(f"Retry after: {e.retry_after}s")
Development Status
Completed ✅
- Generator architecture designed
- Schema file structure created
- Type definitions (5 Literal types)
- Common data structures (5 structures)
- All 18 endpoints documented
- 6 endpoints with complete responses
In Progress ⏳
- Complete schema (12 endpoints missing responses)
- Verify data structures
- Get firmware_profiles structure
Not Started 📋
- Schema parser
- Endpoint generator adaptation
- Template creation
- Code generation
- Testing
- Documentation
- PyPI release
Project Structure
packages/fortiztp/
├── README.md # This file
├── dev/
│ ├── GENERATOR_PLAN.md # Implementation roadmap
│ ├── API_DOCUMENTATION.md # API reference
│ ├── SCHEMA_GAPS_ANALYSIS.md # Missing information checklist
│ ├── generator/
│ │ ├── generate.py # Main generator script (to be created)
│ │ ├── schema/
│ │ │ └── fortiztp_schema.py # ✅ Manual API schema
│ │ ├── parsers/
│ │ │ └── fortiztp_schema_parser.py # Schema parser (to be created)
│ │ ├── generators/
│ │ │ └── endpoint_generator.py # Code generator (to be adapted)
│ │ ├── templates/
│ │ │ ├── endpoint_template.py.tmpl # (to be created)
│ │ │ └── endpoint_template.pyi.tmpl # (to be created)
│ │ └── endpoint_config.py # FortiZTP overrides (to be created)
│ └── tests/ # Generator tests (to be created)
└── src/
└── hfortix_fortiztp/ # Generated SDK code (not yet created)
├── __init__.py
├── models.py # Response classes
├── types.py # Literal type aliases
├── api/
│ └── v2/
│ ├── __init__.py
│ ├── devices/
│ ├── settings/
│ │ ├── scripts/
│ │ └── fortimanagers/
│ └── system/
└── py.typed
Schema Status
Type Definitions (5/5) ✅
- DeviceType
- ProvisionStatus
- ProvisionSubStatus
- ProvisionTarget
- ServiceStatus
Data Structures (5/5) ✅
- DEVICE_V2_DATA (16 properties) - needs verification
- SCRIPT_META_DATA (3 properties) - needs verification
- FORTIMANAGER_META_DATA (5 properties)
- SYSTEM_DATA (4 properties)
- ERROR_RESPONSE (2 properties)
Endpoints (6/18) ⚠️
Complete:
- ✅ GET /v2/setting/fortimanagers
- ✅ POST /v2/setting/fortimanagers
- ✅ GET /v2/setting/fortimanagers/{oid}
- ✅ PUT /v2/setting/fortimanagers/{oid}
- ✅ DELETE /v2/setting/fortimanagers/{oid}
- ✅ GET /v2/system
Missing Response Definitions (12):
- ❌ GET /v2/devices
- ❌ PUT /v2/devices
- ❌ GET /v2/devices/{deviceSN}
- ❌ PUT /v2/devices/{deviceSN}
- ❌ GET /v2/devices/{deviceSN}/regions/{region}/firmwareprofiles
- ❌ GET /v2/setting/scripts
- ❌ POST /v2/setting/scripts
- ❌ GET /v2/setting/scripts/{oid}
- ❌ PUT /v2/setting/scripts/{oid}
- ❌ DELETE /v2/setting/scripts/{oid}
- ❌ GET /v2/setting/scripts/{oid}/content
- ❌ PUT /v2/setting/scripts/{oid}/content
Next Steps
Critical (Blocking Code Generation):
- Get response body examples for 12 missing endpoints
- Verify DEVICE_V2_DATA structure (all 16 fields correct?)
- Get firmware_profiles actual response structure
- Confirm HTTP status codes (200, 201, 204)
Implementation:
- Create schema parser
- Adapt endpoint generator from FortiCare
- Create templates
- Generate code
- Test and validate
Resources
- API Base URL: https://fortiztp.forticloud.com/public/api
- Auth URL: https://customerapiauth.fortinet.com
- API Version: v2.0
- Rate Limit: 2000 calls/hour
- Authentication: OAuth 2.0 (IAM API Users - Local type only)
Contributing
This package is part of the hfortix SDK family:
- hfortix-core: Core HTTP client and utilities
- hfortix-fortios: FortiOS REST API
- hfortix-forticare: FortiCare Asset Management API
- hfortix-fortiztp: FortiZTP Cloud API (this package)
- hfortix: Meta package
See main repository for contribution guidelines.
License
[Your License Here]
Authors
[Your Name/Organization]
Last Updated: February 6, 2026
Schema Version: 2.0 (33% complete)
Status: Development (blocked - awaiting API documentation)
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_fortiztp-0.5.160.tar.gz.
File metadata
- Download URL: hfortix_fortiztp-0.5.160.tar.gz
- Upload date:
- Size: 21.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
503fbdd554477a4db5ca6a23118eef5dcbd3848ec5caf5696c88ba3d86c03de4
|
|
| MD5 |
ec2823257000e6daf5738a227f55de0e
|
|
| BLAKE2b-256 |
515376d6f4382ecd0a4d05f71e944b780585517e24c48fe6428b43790b025ee8
|
File details
Details for the file hfortix_fortiztp-0.5.160-py3-none-any.whl.
File metadata
- Download URL: hfortix_fortiztp-0.5.160-py3-none-any.whl
- Upload date:
- Size: 27.5 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 |
967d05198c4c2177ed3433f6a8a423ebeae82df0aaa495cc5ce80efa41acb106
|
|
| MD5 |
dc911572ab879aebc2bfdfbc045b1a0b
|
|
| BLAKE2b-256 |
97a8ed9b6350d8f306a5aa56f36d32af93677e6c93701e3083c4bf1c8d80dc19
|