FortiCare Asset Management API Client
Project description
hfortix-forticare
Python SDK for Fortinet FortiCare Asset Management V3 API.
Overview
hfortix-forticare provides a fully typed Python interface to the FortiCare Asset Management API, enabling programmatic access to:
- Product Management: Register, list, update, and decommission products
- License Management: Register, list, and download licenses
- Contract Management: View contract information
- Folder Management: Organize assets into folders
- Service Management: Register subscription services
Features
โจ Fully Typed - Complete type hints with TypedDict for request/response structures ๐ Auto-completion - IDE auto-completion for all parameters and return values ๐ OAuth 2.0 - Built-in OAuth Bearer token authentication ๐ Modern HTTP - HTTP/2 support via httpx ๐ฏ Explicit Parameters - All API parameters exposed as function arguments ๐ Rich Documentation - Comprehensive docstrings from Swagger specs
Installation
pip install hfortix-forticare
Quick Start
1. Authentication
You have multiple options for authentication:
Option A: CloudSession (Recommended for Multi-Service)
from hfortix_core.session import CloudSession
from hfortix_forticare import FortiCare
# CloudSession manages tokens for multiple services
with CloudSession(api_id="your_api_id", password="your_password") as session:
fc = FortiCare(session=session) # Auto-uses "assetmanagement" client_id
products = fc.api.products.list.post()
# Token is automatically managed and shared efficiently
Option B: Auto-Login with Credentials
from hfortix_forticare import FortiCare
# Auto-login with API credentials
fcc = FortiCare(
api_id="your_api_id",
password="your_password",
client_id="assetmanagement"
)
# Token is automatically obtained and managed
Option C: Use Pre-Obtained OAuth Token
# Get token from FortiAuthenticator OAuth endpoint first
# https://customerapiauth.fortinet.com/api/v1/oauth/token
fcc = FortiCare(oauth_token="your_oauth_token_here")
2. Use the API
# List products with entitlements
products = fcc.api.products.list.post(
serial_number="FGT*",
status="Registered"
)
# Get product details
details = fcc.api.products.details.post(
serial_number="FGT90D1234567890"
)
# Register a product
result = fcc.api.products.register.post(
registration_units=[
{
"serialNumber": "FGT90D1234567890",
"description": "My FortiGate",
# ... other fields
}
]
)
# List contracts
contracts = fcc.api.contracts.list.post()
# List licenses
licenses = fcc.api.licenses.list.post()
# Manage folders
folders = fcc.api.folders.list.post()
# Always clean up when done
fcc.logout()
API Structure
The SDK mirrors the FortiCare Asset Management V3 API structure:
fcc.api.
โโโ products.
โ โโโ list - List products with entitlements
โ โโโ register - Register products and contracts
โ โโโ details - Get product details
โ โโโ description - Update product description
โ โโโ location - Update product location
โ โโโ folder - Update product folder
โ โโโ decommission - Decommission products
โ โโโ transfer - Transfer products between accounts
โโโ licenses.
โ โโโ list - List licenses
โ โโโ register - Register a license
โ โโโ download - Download VM license file
โโโ contracts.
โ โโโ list - List contracts
โโโ folders.
โ โโโ list - List asset folders
โ โโโ create - Create new folder
โ โโโ delete - Delete folder
โโโ services.
โโโ register - Register subscription service
Type Safety
All endpoints use TypedDict for request and response structures:
# IDE will show all available parameters
products = fcc.api.products.list.post(
serial_number="FGT*", # str
expire_before="2024...", # str (ISO 8601)
status="Registered", # str
product_model="...", # str
account_id=12345 # float
)
# Response is also typed
assert products['status'] == 0 # int
assert isinstance(products['message'], str)
assert isinstance(products['assets'], list)
Rate Limits
FortiCare Asset Management API enforces the following limits:
- 100 calls per minute
- 1000 calls per hour
- 10 errors per hour
- Batch operations: Max 10 units, max 5 errors per batch
Rate Limit Tracking
Track your API usage to stay within limits (tracking only, no enforcement):
from hfortix_forticare import FortiCare
# Configure custom limits (all optional, defaults to None)
fcc = FortiCare(
api_id="...",
password="...",
rate_limit_calls_per_min=100, # FortiCare: 100/min
rate_limit_calls_per_hour=1000, # FortiCare: 1000/hour
rate_limit_errors_per_hour=10 # FortiCare: 10 errors/hour
)
# Make API calls
products = fcc.api.products.list.post()
# Check rate limit status
status = fcc.get_rate_limit_status()
print(f"Calls last min: {status['calls_last_min']}/{status['limits']['calls_per_min']}")
print(f"Calls last 5min: {status['calls_last_5min']}")
print(f"Calls last hour: {status['calls_last_hour']}/{status['limits']['calls_per_hour']}")
print(f"Errors last hour: {status['errors_last_hour']}/{status['limits']['errors_per_hour']}")
print(f"Within limits: {status['within_limits']}")
Note: Rate limiting counters are informational only and do not enforce limits. They help you monitor usage and implement your own rate limiting logic.
Error Handling
try:
result = fcc.api.products.list.post(serial_number="FGT*")
if result['status'] == 0:
print("Success!")
else:
print(f"API Error: {result['message']}")
except httpx.HTTPStatusError as e:
print(f"HTTP Error: {e.response.status_code}")
except httpx.TimeoutException:
print("Request timed out")
except httpx.RequestError as e:
print(f"Network error: {e}")
Context Manager
Use as a context manager for automatic cleanup:
with FortiCare(oauth_token="...") as fcc:
products = fcc.api.products.list.post(...)
# ... use the client ...
# Automatically logged out
Configuration
fcc = FortiCare(
oauth_token="your_token",
base_url="https://support.fortinet.com", # Default
verify=True, # SSL verification
max_retries=3, # Retry attempts
connect_timeout=10.0, # Connection timeout (seconds)
read_timeout=300.0 # Read timeout (seconds)
)
OAuth Token Management
The SDK provides comprehensive OAuth token lifecycle management for long-running applications:
View Login Response
# See the full OAuth response
fcc = FortiCare(api_id="...", password="...")
response = fcc.login(force_refresh=True)
print(f"Access Token: {response['access_token']}")
print(f"Refresh Token: {response['refresh_token']}")
print(f"Expires In: {response['expires_in']} seconds")
Refresh Token
# Efficiently refresh token without re-entering credentials
# (faster than full login)
refresh_response = fcc.refresh_token()
print(f"New token expires in: {refresh_response['expires_in']}s")
Track Token Expiration
# Check time remaining
remaining = fcc.get_token_time_remaining()
print(f"Token valid for {remaining} more seconds")
# Check if expired or expiring soon
if fcc.is_token_expired(buffer_seconds=300): # 5 min buffer
print("Token expiring soon, refreshing...")
fcc.refresh_token()
# Get comprehensive token info
info = fcc.get_token_info()
print(f"Created: {info['created_at_iso']}")
print(f"Expires: {info['expires_at_iso']}")
print(f"Time Remaining: {info['time_remaining']}s")
print(f"Expires Soon: {info['expires_soon']}")
Session Manager Pattern
For long-running applications, implement automatic token refresh:
import time
from threading import Thread
def keep_session_alive(fcc: FortiCare):
"""Background task to maintain valid token"""
while True:
if fcc.is_token_expired(buffer_seconds=300): # 5 min buffer
try:
fcc.refresh_token()
print("Token refreshed successfully")
except Exception as e:
print(f"Refresh failed, re-logging in: {e}")
fcc.login(force_refresh=True)
time.sleep(60) # Check every minute
# Start background thread
fcc = FortiCare(api_id="...", password="...")
Thread(target=keep_session_alive, args=(fcc,), daemon=True).start()
# Your application continues...
while True:
folders = fcc.api.folders.list.post()
# ... process data ...
time.sleep(300)
Examples
See EXAMPLES.py for more comprehensive examples.
Development
Regenerating the SDK
If Fortinet updates the API, regenerate the SDK:
cd packages/forticare/dev/generator
python generate.py --clean
This will:
- Parse updated Swagger JSON files
- Generate all endpoint classes with type hints
- Create .pyi stub files for IDE support
- Generate category and main init.py files
Project Structure
packages/forticare/
โโโ src/
โ โโโ hfortix_forticare/
โ โโโ __init__.py # Main FortiCare client
โ โโโ api/
โ โโโ v3/
โ โโโ __init__.py # V3API class
โ โโโ products/ # Product endpoints
โ โโโ licenses/ # License endpoints
โ โโโ contracts/ # Contract endpoints
โ โโโ folders/ # Folder endpoints
โ โโโ services/ # Service endpoints
โโโ dev/
โ โโโ generator/
โ โโโ generate.py # Code generator
โ โโโ parsers/ # Swagger parsers
โ โโโ generators/ # Code generators
โ โโโ templates/ # Code templates
โ โโโ swagger/ # Swagger JSON files
โโโ README.md
Requirements
- Python 3.10+
- httpx
- hfortix-core
License
Copyright ยฉ 2024 Fortinet, Inc.
Links
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_forticare-0.5.161.tar.gz.
File metadata
- Download URL: hfortix_forticare-0.5.161.tar.gz
- Upload date:
- Size: 32.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8be03b48b94c75a618dfdb7890124bd7f3c6c27edfa9d82b4b4918051bd46fec
|
|
| MD5 |
6ff004e42f33770e6f2b738c1239c90e
|
|
| BLAKE2b-256 |
d7e60cbc3921cb5861517bec5ced53b9fd45cf3c3770e3874ad05ec3dccd349f
|
File details
Details for the file hfortix_forticare-0.5.161-py3-none-any.whl.
File metadata
- Download URL: hfortix_forticare-0.5.161-py3-none-any.whl
- Upload date:
- Size: 66.1 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 |
d702c1f0885c38ae995e5bdb9b7a29db3faf3ac03e62c61bc880ec7c7b17cd04
|
|
| MD5 |
1109f26c84cc532b0090072ba0539ba3
|
|
| BLAKE2b-256 |
006d0f031cf9ab0e68c619ed172513d3ac62a14a21c1a93478b37d23f6366b15
|