-
Notifications
You must be signed in to change notification settings - Fork 0
API Custom Apps
- Methods
- Payload model
- List apps
- Get an app
- Create an app
- Update an app
- Delete an app
- Download an installer
- See also
The resource wraps the /api/v1/library/custom-apps endpoint and exposes five methods:
| Method | Description | Returns |
|---|---|---|
list() |
All custom apps | PayloadList[CustomAppPayload] |
get(id) |
A single app by ID | CustomAppPayload |
create(...) |
Upload an installer and create an app | CustomAppPayload |
update(id, ...) |
Update an app (optionally with a new installer) | CustomAppPayload |
delete(id) |
Delete an app | None |
Most methods return a CustomAppPayload:
| Attribute | Type | Description |
|---|---|---|
id |
str |
The library item ID (UUID) |
name |
str |
Display name |
sha256 |
str |
Installer checksum (use it to verify downloads) |
file_key |
str |
The installer's storage key |
file_url |
str |
A URL to download the installer |
file_size |
int |
Installer size in bytes |
file_updated |
str |
Timestamp the installer was last updated |
file_name |
str |
Property: the installer file name with the upload token stripped |
install_type |
str |
package, zip, or image
|
install_enforcement |
str |
install_once, continuously_enforce, or no_enforcement
|
unzip_location |
str | None |
Destination for zip installs |
audit_script |
str |
Audit script (with continuously_enforce) |
preinstall_script |
str |
Script run before installation |
postinstall_script |
str |
Script run after installation |
restart |
bool |
Whether to restart after installation |
active |
bool |
Whether the app is active |
show_in_self_service |
bool |
Whether the app appears in Self Service |
self_service_category_id |
str | None |
Self Service category ID, when shown |
self_service_recommended |
bool | None |
Whether the app is recommended in Self Service |
created_at |
str |
Creation timestamp |
updated_at |
str |
Last-updated timestamp |
create() and update() take two enums:
InstallType.PACKAGE # "package"
InstallType.ZIP # "zip"
InstallType.IMAGE # "image"
InstallEnforcement.INSTALL_ONCE # "install_once"
InstallEnforcement.CONTINUOUSLY_ENFORCE # "continuously_enforce"
InstallEnforcement.NO_ENFORCEMENT # "no_enforcement"Listed apps are returned in a PayloadList with count and results properties.
with CustomAppsResource(config) as apps:
for app in apps.list().results:
print(f"{app.id} {app.name} ({app.install_type})")with CustomAppsResource(config) as apps:
app = apps.get("d528d739-39e4-44b4-89fd-54bef6b3b25e")
print(app.file_name, app.file_size)Creating an app uploads the installer to storage and then registers the library item. The
file argument must be a pathlib.Path to the installer. The lifecycle scripts
(audit_script, preinstall_script, postinstall_script) are required arguments — pass an
empty string when you don't need one.
The create method returns the created app, including the id.
with CustomAppsResource(config) as apps:
created = apps.create(
name="Example.pkg",
file=Path("payloads/Example.pkg"),
install_type=InstallType.PACKAGE,
install_enforcement=InstallEnforcement.INSTALL_ONCE,
audit_script="",
preinstall_script="",
postinstall_script="",
restart=False,
active=True,
)
print(f"Created {created.name} ({created.id})")Note
Large installers can take a while to process server-side and may briefly return HTTP 503 while Iru finalizes the upload. The client retries automatically with backoff (up to about five minutes) before giving up.
create() and update() raise ValueError when options conflict:
| Rule | Requirement |
|---|---|
audit_script is provided |
install_enforcement must be CONTINUOUSLY_ENFORCE. |
install_type is ZIP
|
unzip_location must be provided. |
install_enforcement is NO_ENFORCEMENT
|
show_in_self_service must be set. |
show_in_self_service is True
|
self_service_category_id must be provided. |
A missing installer file raises FileNotFoundError. To make an app available in Self
Service, supply a self_service_category_id — see
Self Service Categories.
create() and update() accept a reporter argument for surfacing upload progress. It is
optional — omit it and the installer still streams to storage directly from disk. The
reporter type is an internal detail; most integrations don't need it.
Pass only the fields you want to change. Include file to replace the installer binary.
with CustomAppsResource(config) as apps:
# Change metadata only.
updated = apps.update("d528d739-39e4-44b4-89fd-54bef6b3b25e", active=False)
print(f"Updated {updated.name} ({updated.id})")
print(f"active={updated.active}")
# Replace the installer.
apps.update(
"d528d739-39e4-44b4-89fd-54bef6b3b25e",
file=Path("payloads/Example-2.0.pkg"),
)Deleting an app only requires the id and does not return anything.
with CustomAppsResource(config) as apps:
apps.delete("d528d739-39e4-44b4-89fd-54bef6b3b25e")App payloads carry a file_url and a sha256 checksum. Use S3Client to stream the
installer to disk; download_file verifies the checksum and only commits the file if it
matches.
with CustomAppsResource(config) as apps:
app = apps.get("d528d739-39e4-44b4-89fd-54bef6b3b25e")
with S3Client() as transport:
try:
transport.download_file(
app.file_url,
Path(app.file_name),
expected_sha=app.sha256,
)
except PayloadIntegrityError:
print("Downloaded file failed its checksum.")
except PayloadTransferError as error:
print(f"Download failed: {error}")Tip
S3Client is an unauthenticated transport — the file_url carries its own credentials —
so it does not take an ApiConfig. Use it inside its own with block.
- Custom Apps — the on-disk repository format for apps.
- Self Service Categories — find category IDs.
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