shortcutkit
Build, validate, and sign Apple Shortcuts (.shortcut) files from Python.
A shortcut that asks your name and says hello:
from shortcutkit import Shortcut, actions, ref, text
s = Shortcut("Greeting")
name = s.action(actions.ASK, WFAskActionPrompt="What's your name?")
s.action(actions.SHOWRESULT, Text=text("Hello, ", ref(name), "!"))
s.write() # Greeting.shortcut
Shortcut.sign("Greeting.shortcut", "Greeting-signed.shortcut")
Open Greeting-signed.shortcut and Shortcuts adds it to your library. Shortcuts only imports
signed files, and signing needs a Mac with an iCloud login; everything else runs on any OS.
Why
The action catalog is extracted from the Shortcuts app's own frameworks, not written by hand, and one command refreshes it after a macOS update. Earlier libraries kept hand-written lists and are archived (python-shortcuts, shortcuts-js); Cherri is a separate language with its own compiler.
- All 434 built-in actions as constants, so a typo is an
AttributeError. - 1,449 actions from Apple's apps: Reminders, Notes, Messages, Settings, and 73 more.
- Third-party app actions, given their descriptor.
- If, Repeat, Repeat with Each, and Choose from Menu blocks.
- A wrong key or value raises
ValueErrorbefore anything is written. - Pure Python, no dependencies.
A TypeScript package with the same name and data adds compile-time checks.
Install
pip install shortcutkit # Python 3.9+
Usage
These examples build on the one at the top.
Share sheet
from shortcutkit import shortcut_input
s = Shortcut("Page Links", types=["ActionExtension"], input_classes=["WFSafariWebPageContentItem"])
links = s.action(actions.RUNJAVASCRIPTONWEBPAGE, WFInput=shortcut_input(), WFJavaScript="completion(document.links.length)")
s.action(actions.SHOWRESULT, Text=text("Links: ", ref(links)))
Control flow
gid = s.if_(ref(name), "has_any_value")
s.action(actions.SHOWRESULT, Text=text("Hello, ", ref(name)))
s.otherwise(gid)
s.action(actions.SHOWRESULT, Text=text("Hello, stranger"))
s.end_if(gid)
Apple's apps
r = s.action(actions.REMINDERS_CREATE_REMINDER, title=text("Buy milk"), priorityLevel="high")
s.action(actions.NOTES_CREATE_NOTE, name="Shopping", content=text("Added ", ref(r)))
Other apps
Pass the identifier and descriptor yourself; the parameters are not checked.
s.action(
"com.example.app.CreateNoteIntent",
AppIntentDescriptor={
"BundleIdentifier": "com.example.app", "Name": "Example", "TeamIdentifier": "ABCDE12345",
"AppIntentIdentifier": "CreateNoteIntent", "ActionRequiresAppInstallation": True,
},
title=text("Hello"),
body=ref(name),
)
API
| Export | What it does |
|---|---|
Shortcut(name, color=, glyph=, types=, input_classes=) |
A shortcut. |
s.action(id, **params) |
Appends an action and returns it. |
s.if_(subject, condition, value=None), s.otherwise(gid), s.end_if(gid) |
An If block. |
s.repeat_each(items), s.end_repeat_each(gid) |
A Repeat with Each block. |
s.repeat_count(n), s.end_repeat_count(gid) |
A Repeat block. |
s.choose_from_menu(prompt, items), s.menu_item(gid, title), s.end_menu(gid) |
A Choose from Menu block. |
s.write(path=None) |
Writes the unsigned file and returns its path. |
Shortcut.sign(src, dst, mode="anyone") |
Signs a file with shortcuts sign. |
s.to_plist() |
The shortcut as a plist dictionary. |
ref(action) |
An action's output. |
text(*parts) |
A string with references in it. |
variable(name), repeat_item(), repeat_index() |
Named and repeat variables. |
shortcut_input(), clipboard(), current_date(), ask(), device_details(), current_app() |
Special variables. |
actions, ACTIONS, get_action(id) |
Action identifiers and their catalog entries. |
PARAM_KINDS, PARAM_CHOICES, PARAM_VARIABLE_TYPES |
What each parameter accepts. |
CONDITION, ICON_COLORS, PROVENANCE |
If conditions, icon colors, and the build the data came from. |
Documentation
- Shortcut file format
- Built-in actions
- Apple app actions
- Parameter encodings
- How the data was extracted, and what is still approximate
Contributing
Issues and pull requests are welcome. See
CONTRIBUTING.md.
License
MIT.
Metadata
Release files for shortcutkit 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| shortcutkit-1.0.0.tar.gz | 246.9 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| shortcutkit-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 494.9 kB
Release files / shortcutkit-1.0.0.tar.gz
| Download URL | shortcutkit-1.0.0.tar.gz |
|---|---|
| Size | 246.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9fdab2f9e0d87c378e4f1834a7f3fd9b570fabdfbb5ecff21f2615dc164ad13b
|
|
BLAKE2b-256 checksum How to use checksums |
00384dfe7e8fc586f06189cea3cdcd30102f517b0723e204eee72619a7f370f8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / shortcutkit-1.0.0-py3-none-any.whl
| Download URL | shortcutkit-1.0.0-py3-none-any.whl |
|---|---|
| Size | 248.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f59a99de94428b5578914dbc007dc32f9d000e0affadcfb84ee45e7470d99c72
|
|
BLAKE2b-256 checksum How to use checksums |
370c0cad0abe0541392b708494e56bdcbf2402c567780b3a9c4f8207c0841165
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Security for shortcutkit 1.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.