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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.