Skip to main content

SIIHA SDK — Natural language → Google Calendar create-event with dedupe

Project description

SIIHA - SDK

What is SIIHA SDK?

SIIHA is a micro-resilience assistant that blends emotional awareness × suggestion maps × workspace tools.
SIIHA SDK v0.1.9 exposes focused capabilities:

  • Parse natural language → structured event (parse_event, beta)
  • Create Google Calendar events (create_calendar_event) with built-in dedupe
    It’s designed for local OAuth, terminal-first workflows, and consistent behavior across CLI / UI integrations.

Features (v0.1.9)

🗓️ Google Calendar – Create Event

  • zh/EN natural-language parsing for dates/times, location, attendees.
  • Cross-day handling (e.g., 晚上11點到凌晨1點).
  • Absolute dates (2025-09-30, 2025/09/30, 09/30/2025, Sep 30 2025) and AM/PM / zh-AMPM.
  • Location markers 地點:/location:at ...(時間片段不會被當成地點); attendees extraction & dedupe; description pass-through.

🧠 Parser (beta) parse_event(text, tz='Asia/Taipei')

Supported input families (examples reflect current test suite):

  • Now / Later:
    EN now + 90 min, 90 minutes from now, 90 minutes later
    ZH 現在+90分鐘, 一個半小時後, 現在+1.5小時
    start=now, duration from hint,flags lock:now_or_bucket / lock:now_plus / lock:later_hint
  • Relative day + time / range:
    tomorrow 10, tomorrow 10:00-10:30, tomorrow 10PM, 明天早上10點
    in 2 days 10AM, two weeks later 9am, 後天晚上七點
    → first rewrite to concrete date (flag rewrite:relative+time)
  • Absolute date + time / range:
    2025-09-30 14:00, Sep 30 2025 2PM, Sep 30 2025 14:00-15:00,
    8/16 9-11, Sep 30 2025 23:00-01:00, 2025-09-30 11:30PM–2025-10-01 12:30AM,
    zh with date: 2025/9/30 上午9點-10點, Sep 30 2025 下午3點
  • Bucket words:
    later this morning/evening, noon/中午, midnight/午夜, evening meeting tomorrow
  • This/Next weekday:
    next week Monday 10am, next Tuesday 10AM / next Tue 10:00 / next Tue at 10, 下週二 10:00
  • All-day:
    Date-only like Sep 30 2025 → all-day window (flags lock:all_day, all_day)
  • Meta fields:
    location: ... / 地點:...invite ... / attendees: ...duration 45 minutes / for 45 minstitle: / 標題:

Intentional non-coverage (by design in v0.1.9):

  • 明早九點(#33)、早上開會(#42)→ ambiguous; parser returns start=None,end=None instead of guessing.

Other behaviors

  • Auto roll to next day when a “today-only time” has already passed (with a short grace window).
    now/later family anchors to now (no roll).
  • Returns flags (e.g., rolled_to_next_day) and a heuristic confidence.

🔁 Idempotent creation (dedupe)

A newly created event is considered a duplicate iff:

  1. the start instant matches an existing event (RFC3339-equivalent across timezones), and
  2. the normalized title matches (trim, collapse whitespace & commas, case-fold).
    Location / attendees differences do not affect dedupe.

🧩 Configurable

DEFAULT_TIMEZONE, DEFAULT_CALENDAR_ID, GOOGLE_SEND_UPDATES.


Example (natural input)

Meet with Marketing team tomorrow 3PM, location: HQ Meeting Room 2, attendees: debby@example.com


Quickstart

0) Prerequisite

python --version           # >= 3.10 (3.11 recommended)
python -m pip install -U pip
python -m pip install -U build twine pytest

1) OAuth setup (Desktop app)

  1. In Google Cloud Console, create OAuth 2.0 Client (Desktop).
  2. Download the client secrets as credentials.json and place it at the project root.
  3. Run a one-time bootstrap to generate token.json (also kept at root):
python quickstart.py

Required scopes (minimum):

2) Install (editable for development)

cd C:\Users\(YOURFOLDER)\siiha-sdk
python -m build                 # (optional) build wheel & sdist into dist/
python -m pip install -e .      # recommended for local dev

Usage

A) Parse → Create (minimal)

from siiha_sdk.calendar import parse_event, create_calendar_event

text = "下個月 5號 下午3點到4點 和Joshua討論 OAuth,地點:Teams,邀請 debby@example.com
"
parsed = parse_event(text, tz="Asia/Taipei")
# parsed keys: title, body, location, attendees, start, end, timeZone, confidence, flags

res = create_calendar_event(
  title = parsed["title"],
  start_iso = parsed["start"],
  end_iso = parsed["end"],
  location = parsed["location"] or None,
  attendees = parsed["attendees"],
  description= parsed["body"] or None,
  timezone = parsed["timeZone"],
  dedupe = True,
)
print(res) # {'ok': True, 'eventId': ..., 'deduped': False/True, ...}

B) Relative “now” examples

from siiha_sdk.calendar import parse_event
for s in [
    "now + 90 min",
    "90 minutes from now",
    "現在+90分鐘",
    "一個半小時後",
]:
    print(s, "=>", parse_event(s, tz="Asia/Taipei"))

C) Target a test calendar (avoid polluting primary)

  • Set environment variable SIIHA_TEST_CALENDAR_ID=your_test_calendar_id or
  • Override in code:
from siiha_sdk import config
config.DEFAULT_CALENDAR_ID = "your_test_calendar_id"

Dedupe behavior

A newly created event is considered a duplicate iff:

  1. the start instant matches an existing event (RFC3339-equivalent across timezones), and 2 the normalized title matches (trim, whitespace collapse, comma normalization, case-fold).

Location / attendees differences do not affect dedupe.


Tests

Parser smoke test

python tests/quickstart_create_event.py

Dedupe scenarios (creates events)

# (optional) direct events to a test calendar
# PowerShell:
$env:SIIHA_TEST_CALENDAR_ID="your_test_calendar_id"
# Bash:
export SIIHA_TEST_CALENDAR_ID=your_test_calendar_id

python tests/dedupe_scenarios.py

(Tip) You can tag test events by passing description="#SDK_TEST" to create_calendar_event(...) and clean them later via a small script.


Configuration

These live in siiha_sdk/config.py:

  • DEFAULT_TIMEZONE = "Asia/Taipei"
  • DEFAULT_CALENDAR_ID = "primary"
  • GOOGLE_SEND_UPDATES = "all" (Google will email updates to attendees)

Override at runtime:

from siiha_sdk import config
config.DEFAULT_TIMEZONE = "Asia/Tokyo"
config.DEFAULT_CALENDAR_ID = "your_cal_id"
config.GOOGLE_SEND_UPDATES = "none"  # or "externalOnly" / "all"

Known limitations

  • Recurrence, reminders, and conferenceData (Meet links) are not supported yet.
  • Language coverage is focused on common zh/EN patterns; other languages/phrases may need extensions.
  • Description is optional and not auto-generated (except when you pass one).
  • Dedupe checks only within the same local day window at creation time.
  • confidence is a heuristic guidance score.
  • Intentional gaps (v0.1.9): sentences 明早九點,早上開會 are not within the scope of this version.

Security

  • Do not commit credentials.json or token.json.
  • Use a test calendar for automated tests.
  • Principle of least privilege for your Google account.

Versioning & License

  • Versioning: SemVer (MAJOR.MINOR.PATCH). Current: v0.1.9.
  • License: MIT (see LICENSE).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

siiha_sdk-0.1.9.tar.gz (35.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

siiha_sdk-0.1.9-py3-none-any.whl (31.8 kB view details)

Uploaded Python 3

File details

Details for the file siiha_sdk-0.1.9.tar.gz.

File metadata

  • Download URL: siiha_sdk-0.1.9.tar.gz
  • Upload date:
  • Size: 35.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for siiha_sdk-0.1.9.tar.gz
Algorithm Hash digest
SHA256 36a83cc23135827ca3bf7b56b393e71d944234d76bd218b67b28c66f1c185098
MD5 e053c26c3efc74f939eaf1624a99c04c
BLAKE2b-256 c386ee35ba7287034018c2fe877f832186683c1bf8eb71fdeea03e0e25148b93

See more details on using hashes here.

File details

Details for the file siiha_sdk-0.1.9-py3-none-any.whl.

File metadata

  • Download URL: siiha_sdk-0.1.9-py3-none-any.whl
  • Upload date:
  • Size: 31.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.13

File hashes

Hashes for siiha_sdk-0.1.9-py3-none-any.whl
Algorithm Hash digest
SHA256 1ad43b52517dfd69b36776eb1c80fb723fa5453d507de0180930ea02a236f2bb
MD5 c742faa2e8748bdfc50304d01e2d5000
BLAKE2b-256 d29dd080e485583639e6a56c345716c3fb68a7e21f7bbc535f271b44eced88cf

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page