Skip to content

Authoring intents in Python

The Python authoring API mirrors the TypeScript surface exactly — same parameter types, same field names (with snake_case where appropriate), same semantics.

define_intent

from axint import define_intent, param
create_event = define_intent(
name="CreateCalendarEventIntent",
title="Create Calendar Event",
description="Creates a new event on the user's calendar.",
domain="productivity",
params={
"event_title": param.string("Title of the event"),
"start_date": param.date("When the event starts"),
"duration_minutes": param.int("Length of the event in minutes"),
},
entitlements=["com.apple.developer.calendars"],
info_plist_keys=["NSCalendarsUsageDescription"],
is_discoverable=True,
)

All arguments except name, title, description, and domain are optional.

param helpers

PythonTypeScriptSwift type
param.string(desc)param.string(desc)String
param.int(desc)param.int(desc)Int
param.double(desc)param.double(desc)Double
param.float(desc)param.float(desc)Float
param.boolean(desc)param.boolean(desc)Bool
param.date(desc)param.date(desc)Date
param.duration(desc)param.duration(desc)Measurement<UnitDuration>
param.url(desc)param.url(desc)URL
param.number(desc)param.number(desc)Int (legacy alias)

Every helper accepts optional=True and default=<value>:

param.boolean("Whether to include attachments", optional=True, default=False)

Multiple intents per file

Python intent files can define multiple intents — axint parse will pick up every top-level define_intent(...) assignment:

from axint import define_intent, param
send = define_intent(name="SendMessageIntent", title="Send", description="...", domain="messaging")
reply = define_intent(name="ReplyIntent", title="Reply", description="...", domain="messaging")

Return the IR

from axint import define_intent
intent = define_intent(name="X", title="X", description="...", domain="x")
ir = intent.to_ir() # -> IntentIR
print(ir.to_dict()) # -> camelCase JSON matching the TS schema

The to_dict() output uses camelCase keys (isDiscoverable, infoPlistKeys) because that’s the cross-language contract shared with the TypeScript compiler.