juno.reminders

Read and write the on-device reminders database (Apple Reminders).

Wraps EventKit’s EKEventStore for reminder fetch / create / complete / delete. Calendar enumeration is exposed so users can pick a destination for new reminders; add() defaults to the system’s default calendar when none is specified.

Authorization is requested lazily by the read/write helpers; the prompt is presented once per fresh install and the resolved status is reused thereafter. Stop is responsive while the iOS prompt is on screen — pressing Stop raises KeyboardInterrupt.

Typical usage:

from juno import reminders
import datetime

if reminders.request_authorization() != reminders.AuthorizationStatus.AUTHORIZED:
    raise SystemExit("reminders permission needed")

for r in reminders.get_all(completed=False):
    print(r.title, r.due_date)

new = reminders.add(reminders.Reminder(
    title="Buy milk",
    notes="2% organic",
    due_date=datetime.datetime(2026, 5, 1, 18, 0),
    priority=reminders.Priority.HIGH,
))
reminders.complete(new)

Limitations:

  • writeOnly authorization (iOS 17+) reports via authorization_status() but is_authorized() returns False for it — read paths can’t enumerate the store under that grant. Users wanting partial-access support can branch on the status string explicitly.

  • Recurrence rules, alarms, geofences, and structured sub-tasks are not exposed; this wrapper covers the “list / add / complete / delete simple reminder” surface that scripts most commonly need.

class juno.reminders.AuthorizationStatus

Bases: object

String constants returned by authorization_status().

class juno.reminders.Priority

Bases: object

EventKit reminder-priority constants.

EventKit encodes priority as 0–9 with non-uniform semantics: 0 is “no priority”, 1 is the highest, 5 is medium, 9 is lowest. The Reminders app surfaces three buckets (None / High / Medium / Low) which map to these named values.

class juno.reminders.Calendar(identifier='', title='', color='', is_subscribed=False, allows_modifying=True)

Bases: object

A reminders-capable calendar.

color is "#RRGGBB" (best-effort hex from the system’s display-P3 RGB; matches what the Reminders app shows). "" on the rare calendar with no color set.

Parameters:
  • identifier (str)

  • title (str)

  • color (str)

  • is_subscribed (bool)

  • allows_modifying (bool)

class juno.reminders.Reminder(identifier='', title='', notes='', due_date=None, is_completed=False, completion_date=None, priority=0, calendar_id='')

Bases: object

A single reminder.

All fields default so a partial Reminder can be passed to add() without ceremony. identifier and completion_date are assigned by iOS — they’re empty / None on a freshly-constructed (not-yet-saved) reminder. priority follows EventKit’s 0–9 convention; see Priority. calendar_id empty means “use the default calendar for new reminders”.

Parameters:
juno.reminders.authorization_status()

Return the current reminders authorization status.

Returns:

One of the AuthorizationStatus string constants.

Return type:

str

juno.reminders.is_authorized()

Return True if the app has full reminders authorization.

iOS 17 writeOnly access returns False — callers wanting partial-access support must branch on authorization_status() directly.

Return type:

bool

juno.reminders.request_authorization()

Request reminders authorization if status is undetermined.

If the status is already determined, returns immediately with the existing value. Otherwise this triggers the system permission prompt and blocks until the user resolves it. Pressing Juno’s Stop button while the prompt is on screen raises a KeyboardInterrupt.

Returns:

Resolved authorization status, one of the AuthorizationStatus constants.

Return type:

str

juno.reminders.calendars()

Return every reminders-capable calendar visible to the app.

Raises:
  • PermissionError – If reminders authorization is denied, restricted, or write-only.

  • RuntimeError – If the calendar enumeration failed.

Return type:

list[Calendar]

juno.reminders.default_calendar()

Return the system’s default calendar for new reminders, or None if no default is configured.

Raises:

PermissionError – If reminders authorization is denied, restricted, or write-only.

Return type:

Calendar | None

juno.reminders.get_all(*, completed=None)

Return reminders matching an optional completion filter.

Parameters:

completed (bool | None) – None (default) returns every reminder. False returns only incomplete ones; True returns only completed ones.

Returns:

A list of Reminder records. Empty when the store has no matches under the filter.

Raises:
Return type:

list[Reminder]

juno.reminders.get(identifier)

Fetch a single reminder by its system identifier.

Parameters:

identifier (str) – The opaque calendarItemIdentifier returned by an earlier get_all() / add() / complete().

Returns:

The Reminder, or None if no reminder with that identifier exists.

Raises:
  • TypeError – If identifier is not a string.

  • PermissionError – If reminders authorization is denied, restricted, or write-only.

Return type:

Reminder | None

juno.reminders.add(reminder)

Persist a new reminder to the user’s database.

The reminder lands in reminder.calendar_id if it is set, or the system’s default calendar for new reminders otherwise.

Parameters:

reminder (Reminder) – The Reminder to add. identifier and completion_date are ignored on input.

Returns:

A fresh Reminder carrying the assigned identifier and saved fields.

Raises:
  • TypeError – If reminder is not a Reminder, or its fields have the wrong runtime type.

  • ValueError – If priority is outside 0–9.

  • PermissionError – If reminders authorization is denied, restricted, or write-only.

  • RuntimeError – If the save failed (no default calendar configured, framework rejected the data, etc.).

Return type:

Reminder

juno.reminders.complete(reminder)

Mark a reminder as completed.

Parameters:

reminder (Reminder | str) – A previously-fetched Reminder, or its identifier string directly.

Returns:

The updated Reminder with is_completed=True and completion_date set to now.

Raises:
Return type:

Reminder

juno.reminders.uncomplete(reminder)

Mark a previously-completed reminder as not-yet-completed.

Clears completion_date and sets is_completed=False. Mirror of complete(); same arguments and exceptions.

Parameters:

reminder (Reminder | str)

Return type:

Reminder

juno.reminders.delete(reminder)

Delete a reminder by Reminder or identifier string.

Parameters:

reminder (Reminder | str) – A previously-fetched Reminder, or its identifier string directly.

Returns:

True if the reminder was deleted, False if no reminder with that identifier exists or the delete failed.

Raises:
Return type:

bool