-
Notifications
You must be signed in to change notification settings - Fork 0
API Client
iructl ships the same Python client module it uses internally at iructl.api.
This page covers the setup shared by every resource: installation, authentication, sessions, and error handling. Each endpoint has its own resource class with a dedicated page of worked examples.
from iructl.api import (
# Configuration
ApiConfig,
# Custom profiles
CustomProfilesResource, CustomProfilePayload,
# Custom scripts
CustomScriptsResource, CustomScriptPayload, ExecutionFrequency,
# Custom apps
CustomAppsResource, CustomAppPayload, InstallType, InstallEnforcement,
# Blueprints
BlueprintsResource, BlueprintPayload, is_duplicate_assignment,
# Self Service categories
SelfServiceCategoriesResource, SelfServiceCategoryPayload,
# Installer transfer
S3Client,
# List results
PayloadList,
)- Installation and import
- Authentication
- Resource classes
- Opening a session
- Working with results
- Error handling
The API client is installed as part of the iructl package. Add a dependency based on
whichever method best fits your project's workflow:
# uv
uv add iructl# poetry
poetry add iructl# pip
echo "iructl" >> requirements.txt
pip install -r requirements.txtClient resources are configured with an ApiConfig, which holds your tenant URL and API token:
from iructl.api import ApiConfig
config = ApiConfig(
tenant_url="https://mycompany.api.iru.com",
api_token="12345678-1234-4234-8234-123456789012",
)Warning
Your API token is a private secret and should never be hardcoded in source code. Best practice is to read it from the environment or inject it from a secret store such as the macOS Keychain.
ApiConfig validates its inputs up front and raises a pydantic.ValidationError if either
value is malformed:
-
Tenant URL — normalized to
https://and must be a supported API host. Valid forms:https://<subdomain>.api.kandji.iohttps://<subdomain>.api.eu.kandji.iohttps://<subdomain>.api.iru.com
-
API token — must be a UUID4 string, e.g.
12345678-1234-4234-8234-123456789012.
A resource class is a thin wrapper around a single API endpoint. It exposes that endpoint's
operations (such as list() and get()) as methods, manages its own authenticated HTTP
session, and returns parsed pydantic models rather than raw
JSON.
The client ships one resource class per endpoint:
- CustomProfilesResource
- CustomScriptsResource
- CustomAppsResource
- BlueprintsResource
- SelfServiceCategoriesResource
A resource manages its own session. The recommended pattern is a with block, which opens
the session on entry and closes it on exit:
from iructl.api import ApiConfig, CustomProfilesResource
config = ApiConfig(
tenant_url="https://mycompany.api.kandji.io",
api_token="12345678-1234-4234-8234-123456789012",
)
with CustomProfilesResource(config) as profiles:
for profile in profiles.list().results:
print(profile.name)If a with block doesn't fit your control flow, open and close the session manually:
profiles = CustomProfilesResource(config)
profiles.open()
try:
profiles.list()
finally:
profiles.close()Important
Calling a resource method before the session is open (or after close) raises ApiClientError. Always use a
with block or call open() first.
Methods return parsed pydantic models rather than raw JSON, so
you get typed attribute access and validation for free. Each resource page documents the
model it returns. In most cases, list methods return a PayloadList containing the returned results.
| Attribute | Type | Description |
|---|---|---|
count |
int |
Total number of items reported by the API |
results |
list[PayloadType] |
Every item, combined across all pages |
next |
str | None |
Internal pagination cursor, consumed by list()
|
previous |
str | None |
Internal pagination cursor, consumed by list()
|
with CustomProfilesResource(config) as profiles:
page = profiles.list()
print(page.count) # total reported by the API
print(len(page.results)) # every profile, across all pagesNote
List endpoints are paginated on the server, but list() handles that for you: it follows
every page and returns a single PayloadList with the combined results. You rarely need to
deal with pagination yourself.
The client raises a small set of exceptions. The iructl-specific ones live in
iructl.exceptions:
| Exception | Raised when |
|---|---|
ApiClientError |
A resource method is called before its session is open. |
PayloadTransferError |
An installer binary fails to upload to or download from S3. |
PayloadIntegrityError |
A downloaded installer fails its sha256 check (subclass of PayloadTransferError). |
Errors from the underlying libraries pass through unchanged:
| Exception | Raised when |
|---|---|
requests.HTTPError |
The API returns a non-2xx status code. |
requests.ConnectionError |
The connection to the API fails. |
pydantic.ValidationError |
A response (or an ApiConfig) doesn't match the expected schema. |
ValueError / FileNotFoundError
|
Invalid arguments are passed (e.g. a missing file, or a mutually exclusive option combination). |
Getting Started
Working with Resources
- Populating Your Local Repository
- Editing Resources
- Self Service
- Pushing and Syncing
- Listing and Showing Resources
- Deleting Resources
- Blueprint Assignment
Reference
Python API Client