JamfClient#

class JamfClient(config: ConfigManager, concurrency: int)[source]#

Fetches patch-management data, device inventory, and OS versions from Jamf Pro.

Provides methods for interacting with the Jamf API, specifically fetching patch data, device information, and OS versions.

Note

All methods of the JamfClient class will raise an APIResponseError if the API call is unsuccessful.

Parameters:
  • config (ConfigManager) โ€“ Instance of ConfigManager for loading and storing credentials.

  • concurrency (int) โ€“ Maximum number of concurrent API requests. See concurrency in Usage docs.

async aclose() None[source]#

Release this clientโ€™s connection pool and the token managerโ€™s.

Return type:

None

classmethod from_credentials(client_id: str, client_secret: str, server: str, concurrency: int = 5) JamfClient[source]#

Construct an JamfClient directly from credentials, bypassing the macOS keychain. Intended for library and CI/CD use.

Wraps the inputs in an in-memory ConfigManager (the same path the CLI uses for non-interactive mode) so no keyring backend is required and nothing is persisted to disk.

from patcher import JamfClient

client = JamfClient.from_credentials(
    client_id="...",
    client_secret="...",
    server="https://myorg.jamfcloud.com",
)
summaries = await client.get_summaries(await client.get_policies())
Parameters:
  • client_id (str) โ€“ Jamf Pro API client ID.

  • client_secret (str) โ€“ Jamf Pro API client secret.

  • server (str) โ€“ Jamf Pro instance URL (e.g. https://myorg.jamfcloud.com).

  • concurrency (int) โ€“ Maximum concurrent API requests. Defaults to 5, the recommended ceiling per the Jamf Developer Guide.

Returns:

A constructed JamfClient ready for use.

Return type:

JamfClient

async _headers() dict[str, str][source]#

Generates headers for API calls, ensuring the latest token is used.

Return type:

dict[str, str]

async get_title_configs() list[dict][source]#

Fetch the full patch software title configurations.

Important

Each config carries id and softwareTitleNameId which are easy to conflate. softwareTitleNameId is the global catalog code used for deterministic matching.

Return type:

list[dict]

async get_policies() list[str][source]#

Retrieve the list of patch software title IDs from the Jamf API.

Return type:

list[str]

async get_summaries(policy_ids: list[str]) list[PatchTitle][source]#

Retrieves patch summaries asynchronously for the specified policy IDs from the Jamf API.

Parameters:

policy_ids (list[str]) โ€“ list of policy IDs to retrieve summaries for.

Returns:

list of PatchTitle objects containing patch summaries.

Return type:

list[PatchTitle]

async get_title_report_csv(title_id: str) list[PatchDevice][source]#

Retrieve the complete patch report for a specific software title using the CSV export endpoint.

This method fetches all device data in a single CSV request, avoiding pagination entirely.

Parameters:

title_id (str) โ€“ The software title ID to retrieve the patch report for.

Returns:

List of all PatchDevice objects for the title.

Return type:

list[PatchDevice]

Raises:

APIResponseError โ€“ If the CSV export fails or returns non-200 status.

async get_title_reports(title_ids: list[str]) dict[str, list[PatchDevice]][source]#

Retrieves patch reports for multiple software titles.

Processes titles sequentially to avoid overwhelming the Jamf API. Each titleโ€™s pagination is handled by the underlying stream/fetch methods.

Parameters:

title_ids (list[str]) โ€“ List of software title IDs to retrieve reports for.

Returns:

Dictionary mapping title IDs to lists of PatchDevice objects.

Return type:

dict[str, list[PatchDevice]]

async get_device_ids() list[int][source]#

Asynchronously fetches the list of mobile device IDs from the Jamf Pro API.

Note

This method is only called if the iOS option is passed to the CLI.

Returns:

A list of mobile device IDs.

Return type:

list[int]

async get_device_os_versions(device_ids: list[int]) list[dict[str, str]][source]#

Asynchronously fetches the OS version and serial number for each device ID provided.

Note

This method is only called if the iOS option is passed to the CLI.

Parameters:

device_ids (list[int]) โ€“ A list of mobile device IDs to retrieve information for.

Returns:

A list of dictionaries containing the serial numbers and OS versions.

Return type:

list[dict[str, str]]

async get_app_names(patch_titles: list[PatchTitle]) list[dict[str, Any]][source]#

Fetches all possible app names for each PatchTitle object provided.

Parameters:

patch_titles (list[PatchTitle]) โ€“ list of PatchTitle objects.

Returns:

list of dictionaries containing the PatchTitle title and corresponding appName

Return type:

list[dict[str, Any]]

JamfSetupClient#

class JamfSetupClient(jamf_url: str, max_concurrency: int = 5)[source]#

Credential-free Jamf client for the first-run provisioning flow (basic-token auth + API role/client creation).

A Jamf client for the pre-credential setup flow.

Unlike JamfClient, it needs no stored credentials at construction (only the instance URL), because it runs before an API client exists; it is what mints one. Username/password and the basic token are passed per call to the provisioning methods.

Parameters:
  • jamf_url (str) โ€“ The Jamf Pro instance URL to provision against.

  • max_concurrency (int) โ€“ Maximum number of concurrent API requests.

async fetch_basic_token(username: str, password: str) str[source]#

Asynchronously retrieves a basic token using HTTP Basic authentication.

This method is intended for initial setup to obtain client credentials for API clients and roles. It should not be used for regular token retrieval after setup.

The password is passed via httpxโ€™s auth= tuple parameter, which encodes it in the Authorization header. It never appears in the URL, request body, or log output, so no credential-sanitization step is required on the error path.

Parameters:
  • username (str) โ€“ Username of admin Jamf Pro account for authentication. Not permanently stored, only used for initial token retrieval.

  • password (str) โ€“ Password of admin Jamf Pro account. Not permanently stored, only used for initial token retrieval.

Returns:

The BasicToken string.

Return type:

str

Raises:

APIResponseError โ€“ If the call is unauthorized, unsuccessful, or the response body doesnโ€™t contain a token field.

async create_roles(token: str) bool[source]#

Creates the necessary API roles using the provided basic token.

See also

ApiRoleModel

Parameters:

token (str) โ€“ The basic token to use for authentication.

Returns:

True if roles were successfully created, False otherwise.

Return type:

bool

async create_client(token: str) tuple[str, str][source]#

Creates an API client and retrieves its client ID and client secret.

See also

ApiClientModel

Parameters:

token (str) โ€“ The basic token to use for authentication.

Returns:

A tuple containing the client ID and client secret.

Return type:

tuple[str, str]