schemas¶
Pydantic models the API uses for response serialization (and a few request bodies). One module per source’s payload shape, plus shared schemas for apps, drift, and labels.
App¶
- class InstallMethod(*values)[source]¶
Mirrors Installomator’s type variable.
See https://github.com/Installomator/Installomator/wiki/Label-Variables-Reference for the upstream definition.
- class App(*, slug: str, bundle_id: str | None = None, name: str, vendor: str | None = None, current_version: str | None = None, latest_release_date: date | None = None, download_url: HttpUrl | None = None, install_method: InstallMethod | None = None, sha256: str | None = None, sources: list[str])[source]¶
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
Sources (composite payload)¶
- class InstallomatorSource(*, label_name: str, label_url: HttpUrl, raw: dict)[source]¶
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class HomebrewCaskSource(*, token: str, cask_json: dict)[source]¶
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class AutopkgRecipeEntry(*, identifier: str, name: str | None = None, shortname: str | None = None, repo: str, path: str, parent_identifier: str | None = None, inferred_type: str | None = None, recipe_url: HttpUrl | None = None)[source]¶
Single recipe attached to an app via the AutoPkg index.
nameandshortnameare optional, mirroring the upstream index (and theAutopkgIndexEntryingest schema): shared-processor recipes carryname: nulland some app recipes have no cleanshortname. The response must tolerate theNonethat stitch faithfully stored, or/apps/{slug}/sources500s for any app whose matched recipes lack one.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class AutopkgSource(*, recipes: list[AutopkgRecipeEntry])[source]¶
All AutoPkg recipes matched to an app via the recipe index.
AutoPkg coverage is multi-recipe by nature: a single app like Firefox typically has download, munki, pkg, jamf, and intune variants across multiple maintainer repos. Each match is preserved as a separate
AutopkgRecipeEntry.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- Parameters:
recipes (list[AutopkgRecipeEntry])
- class MasSource(*, bundle_id: str, store_url: HttpUrl | None = None, raw: dict)[source]¶
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class JamfAppInstallerSource(*, title: str, source: str, host: str | None = None, bundle_id: str | None = None, version: str | None = None, jamf_id: str | None = None, download_url: str | None = None, architecture: str | None = None)[source]¶
Jamf App Installers catalog coverage for an app.
title/source/hostcome from the public HTML catalog; the rest is enrichment from the App Installers titles API (absent on HTML-only rows, hence optional).Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class AppSources(*, installomator: InstallomatorSource | None = None, homebrew_cask: HomebrewCaskSource | None = None, autopkg: AutopkgSource | None = None, mas: MasSource | None = None, jamf_app_installer: JamfAppInstallerSource | None = None)[source]¶
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- Parameters:
installomator (InstallomatorSource | None)
homebrew_cask (HomebrewCaskSource | None)
autopkg (AutopkgSource | None)
mas (MasSource | None)
jamf_app_installer (JamfAppInstallerSource | None)
Drift¶
- class SourceVersion(*, source: str, version: str, parsed_ok: bool)[source]¶
One source’s reported version for an app.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class DriftEntry(*, slug: str, name: str, vendor: str | None = None, versions: list[SourceVersion], leader: str | None = None, laggard: str | None = None)[source]¶
Drift detected on a single app.
leaderandlaggardare the source names with the highest and lowest parsed versions; both areNonewhen at least one version string couldn’t be parsed (e.g. Cask’s2025-04-15date-style versions). In that caseversionsis still complete and consumers can render the disagreement without ordering it.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class DriftResponse(*, total_scanned: int, total_with_drift: int, entries: list[DriftEntry])[source]¶
Paginated drift results across the catalog.
total_scannedis the number of apps inspected (those with ≥2 versioned sources);total_with_driftis the subset where the sources disagreed.entriesis the page of disagreements.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- Parameters:
total_scanned (int)
total_with_drift (int)
entries (list[DriftEntry])
Labels¶
- class GenerateLabelResponse(*, label_name: str, content: dict[str, Any], sources_used: list[str], warnings: list[str])[source]¶
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
Homebrew Cask¶
- class HomebrewCaskRecord(*, token: str, name: list[str], desc: str | None = None, homepage: str | None = None, url: str | None = None, version: str | None = None, sha256: str | None = None, auto_updates: bool | None = None, depends_on: dict | None = None, artifacts: list[dict] = [])[source]¶
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
AutoPkg¶
- class AutopkgIndexEntry(*, name: str | None = None, description: str | None = None, repo: str, path: str, parent: str | None = None, shortname: str | None = None, inferred_type: str | None = None, children: list[str] = [])[source]¶
A single recipe entry as it appears in the value of an
identifiersmap key in upstreamindex.json. The map’s key (the reverse-DNS identifier likecom.github.autopkg.download.Firefox) is passed separately when ingesting; it is not part of the entry value.nameandshortnameare intentionally optional because the upstream index has substantial inconsistency on these fields. Shared- processor utility recipes typically havename: null; some app recipes have unusualshortnamevalues (often containing special characters like.or whitespace) that the index doesn’t capture cleanly. Preserving these rows keeps the catalog complete; the stitch matching logic already gates on a non-empty normalized name, so recipes without one naturally never attach to apps.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
Jamf App Installers¶
- class JaiMediaSource(*, url: str, hash: str | None = None, hashType: str | None = None)[source]¶
One download source for a title — titles often carry one per architecture.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- class JaiTitle(*, id: str, bundleId: str | None = None, titleName: str, publisher: str | None = None, iconUrl: str | None = None, version: str | None = None, shortVersion: str | None = None, architecture: str | None = None, minimumOsVersion: str | None = None, language: str | None = None, availabilityDate: datetime | None = None, mediaSourceType: str | None = None, originalMediaSources: list[JaiMediaSource] = <factory>, sizeInBytes: int | None = None, installationPathShared: bool | None = None, packageSigningIdentity: str | None = None, installerPackageHash: str | None = None, installerPackageHashType: str | None = None, launchDaemonIncluded: bool | None = None, notificationAvailable: bool | None = None, suppressAutoUpdate: bool | None = None, originalTermsAndConditions: list[Any] = <factory>)[source]¶
A Jamf App Installers catalog title.
The list endpoint returns the leading identity fields; the per-title detail endpoint adds the rest. Everything past
title_nameis optional, so the same model parses both shapes. Aliases are auto-generated camelCase except the twooriginal*fields, whose wire names don’t follow from the snake_case field name.Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
- Parameters:
id (str)
bundleId (str | None)
titleName (str)
publisher (str | None)
iconUrl (str | None)
version (str | None)
shortVersion (str | None)
architecture (str | None)
minimumOsVersion (str | None)
language (str | None)
availabilityDate (datetime | None)
mediaSourceType (str | None)
originalMediaSources (list[JaiMediaSource])
sizeInBytes (int | None)
installationPathShared (bool | None)
packageSigningIdentity (str | None)
installerPackageHash (str | None)
installerPackageHashType (str | None)
launchDaemonIncluded (bool | None)
notificationAvailable (bool | None)
suppressAutoUpdate (bool | None)
- class JaiTitlePage(*, totalCount: int, results: list[JaiTitle])[source]¶
One page of
GET /api/v1/app-installers/titles(totalCount+results).Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.
Mac App Store¶
- class MasLookupRecord(*, bundleId: str, trackName: str, version: str | None = None, releaseDate: str | None = None, releaseNotes: str | None = None, trackViewUrl: str | None = None, minimumOsVersion: str | None = None, price: float | None = None, kind: str | None = None)[source]¶
Single result from the lookup endpoint.
Apple returns the fields camelCase as documented. We accept them verbatim here and project to snake_case at the model boundary, matching the pattern used for Homebrew Cask and Installomator records.
Create a new model by parsing and validating input data from keyword arguments.
Raises [ValidationError][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.
self is explicitly positional-only to allow self as a field name.