Python SDK and CLI for AnyMoment API - Create and manage your schedule with natural language, write moments the way you think them.
Project description
AnyMoment Python SDK & CLI
Python SDK and command-line interface for the AnyMoment API - Create and manage recurring calendar events with natural language.
📖 Full documentation (Python SDK & CLI) — installation, quick start, all CLI commands, and Library API reference.
Features
- 🎯 Natural Language Event Creation - Create complex recurring events from simple text
- 📅 Full Calendar Management - Create, update, delete, and share calendars
- 🔐 Secure Token Management - Encrypted token storage with automatic refresh
- 🚀 Both Library & CLI - Use programmatically or from the command line
- ⚡ Fast & Reliable - Built on requests with proper error handling
Installation
Library Only
pip install anymoment
With CLI
pip install anymoment[cli]
Quick Start
CLI Usage
# Login
anymoment auth login
# Create a calendar
anymoment calendars create "Work Calendar" --timezone "America/New_York"
# Create an event from natural language
anymoment events create "Weekly team meeting every Monday at 10 AM" \
--calendar <calendar-id>
# List events
anymoment events list --calendar <calendar-id>
# Get event instances for a date range
anymoment events instances <event-id> --from "2026-01-01" --to "2026-03-31"
Library Usage
from anymoment import Client
# Initialize client
client = Client(api_url="https://api.anymoment.sineways.tech")
# Login
client.login(email="user@example.com", password="secret")
# Create calendar
calendar = client.create_calendar(
name="Work Calendar",
timezone="America/New_York"
)
# Create event from natural language
event = client.create_event_from_text(
recurrence_text="Weekly team meeting every Monday at 10 AM",
calendar_id=calendar["id"]
)
# Get event instances for a date range
instances = client.get_event_instances(
event_id=event["id"],
from_date="2026-01-01",
to_date="2026-03-31"
)
Configuration
Environment Variables
ANYMOMENT_BASE_URL- Default API base URL (default:https://api.anymoment.sineways.tech)ANYMOMENT_DEFAULT_CALENDAR- Default calendar IDANYMOMENT_DEFAULT_TIMEZONE- Default timezone
Config File
Configuration is stored in ~/.anymoment/config.json. You can manage it via CLI:
# Set default API URL
anymoment config set-url https://api.anymoment.sineways.tech
# Set default timezone
anymoment config set-timezone America/New_York
# Set default calendar
anymoment config set-calendar <calendar-id>
# Show current config
anymoment config show
CLI Commands
Authentication
# Login interactively
anymoment auth login [--host URL]
# Logout (clear token)
anymoment auth logout [--host URL]
# List all tokens
anymoment tokens list
# Clear all tokens
anymoment tokens clear
Calendars
# List calendars
anymoment calendars list [--active/--inactive] [--limit N] [--offset N]
# Create calendar
anymoment calendars create <name> [--description TEXT] [--timezone TZ] [--color COLOR]
# Get calendar details
anymoment calendars get <id>
# Update calendar
anymoment calendars update <id> [--name NAME] [--description TEXT] [--timezone TZ] [--color COLOR] [--active/--inactive]
# Delete calendar
anymoment calendars delete <id>
# Share calendar with another user (set role: owner, editor, viewer)
anymoment calendars share <id> <user-id> [--role ROLE]
# Update a shared user's role
anymoment calendars update-share <id> <user-id> --role ROLE
# Remove share (user loses access unless linked via Google)
anymoment calendars unshare <id> <user-id>
# Add / remove events to or from a calendar (link or unlink)
anymoment calendars add-event <calendar-id> <event-id> [--display-order N] [--color COLOR]
anymoment calendars remove-event <calendar-id> <event-id>
# Batch add or remove events to or from a calendar
anymoment calendars batch-add-events <calendar-id> <event-id> [<event-id> ...] [--display-order N] [--color COLOR]
anymoment calendars batch-remove-events <calendar-id> <event-id> [<event-id> ...]
# Get webhook URL
anymoment calendars webhook-url <id>
Events
# Create event from natural language
anymoment events create "TEXT" [--name NAME] [--description TEXT] [--timezone TZ] [--calendar ID] [--model MODEL]
# List events
anymoment events list [--calendar ID] [--active/--inactive] [--limit N] [--offset N] [--minimal]
Note: To filter events by date range, use `events instances` instead.
# Get event details
anymoment events get <id>
# Update event
anymoment events update <id> [--name NAME] [--description TEXT]
# Delete event
anymoment events delete <id>
# Toggle event active status
anymoment events toggle <id>
# Get event instances
anymoment events instances <id> [--from DATE] [--to DATE] [--optimized]
# Get next instance
anymoment events next <id>
# Export instances
anymoment events export <id> [--format ics|csv] [--from DATE] [--to DATE] [--out FILE]
Agenda & Search
# List events and instances in a time window (agenda)
anymoment agenda list [--start ISO] [--end ISO] [--calendar ID] [--no-cache] [--webhooks]
# Fuzzy search events by name (optional time window and filters)
anymoment agenda search <query> [--start ISO] [--end ISO] [--calendar ID] [--active/--inactive] [--limit N] [--offset N] [--no-instances]
Users
# Show current user info
anymoment users me
Common Options
--host, -h URL- Override API host URL (env:ANYMOMENT_BASE_URL)--raw- Output full JSON response--pipe- Output only IDs (for piping/chaining)--timezone, -z TZ- Override timezone for this command--calendar, -c ID- Specify calendar ID (or use default from config)
Library API Reference
Client Class
from anymoment import Client
client = Client(api_url="https://api.anymoment.sineways.tech", token="optional-token")
Authentication
client.login(email, password)- Authenticate and get tokenclient.refresh_token()- Refresh current tokenclient.get_user_info()- Get current user information
Calendars
client.list_calendars(is_active=None, limit=None, offset=None)- List calendarsclient.get_calendar(calendar_id)- Get calendar by IDclient.create_calendar(name, description=None, timezone="UTC", color=None)- Create calendarclient.update_calendar(calendar_id, name=None, description=None, timezone=None, color=None, is_active=None)- Update calendarclient.delete_calendar(calendar_id)- Delete calendarclient.share_calendar(calendar_id, user_id, role="viewer")- Share calendar with a user (set permissions)client.update_calendar_share_role(calendar_id, user_id, role)- Update a shared user's role (owner, editor, viewer)client.unshare_calendar(calendar_id, user_id)- Remove an AnyMoment share for a calendarclient.get_calendar_webhook_url(calendar_id)- Get webhook URL
Events
client.list_events(calendar_id=None, is_active=None, limit=None, offset=None, minimal=False)- List eventsclient.get_event(event_id)- Get event by IDclient.create_event_from_text(recurrence_text, name=None, description=None, timezone="UTC", calendar_id=None, model="high")- Create event from natural languageclient.update_event(event_id, name=None, description=None)- Update eventclient.delete_event(event_id)- Delete eventclient.toggle_event(event_id)- Toggle event active statusclient.get_event_instances(event_id, from_date=None, to_date=None, optimized=False)- Get event instancesclient.get_next_event_instance(event_id)- Get next instance
Agenda & Search
client.get_agenda(start, end, calendar_ids=None, use_cache=True, include_webhooks=False)- Get events and their instances within a time window (agenda)client.search_events(q, start=None, end=None, calendar_ids=None, is_active=None, limit=50, offset=0, include_instances=True)- Fuzzy search events by name (optional time window and filters)
Calendar-Event Links (add / remove events to or from calendars)
client.link_event_to_calendar(calendar_id, event_id, display_order=None, color_override=None)- Add one event to a calendarclient.unlink_event_from_calendar(calendar_id, event_id)- Remove one event from a calendar (unlink only; event is not deleted)client.batch_add_events_to_calendar(calendar_id, event_ids, display_order=None, color_override=None)- Add multiple events to a calendar in one requestclient.batch_remove_events_from_calendar(calendar_id, event_ids)- Remove multiple events from a calendar (unlink only)
Examples
Natural Language Event Creation
# Simple weekly event
event = client.create_event_from_text(recurrence_text="Every Monday at 10 AM")
# Complex recurring pattern
event = client.create_event_from_text(
recurrence_text="Weekdays from 9 to 5, except the 13th of every month",
name="Work Hours",
timezone="America/New_York"
)
# Multiple time windows
event = client.create_event_from_text(
recurrence_text="Every Monday and Wednesday, from 9:00 to 12:00 and 13:00 to 17:00"
)
Working with Calendars
# Create and configure calendar
calendar = client.create_calendar(
name="Personal",
description="Personal events",
timezone="America/New_York",
color="#FF5733"
)
# Share with another user
client.share_calendar(
calendar_id=calendar["id"],
user_id="other-user-id",
role="viewer"
)
# Get webhook URL for automation
webhook = client.get_calendar_webhook_url(calendar["id"])
print(f"Webhook URL: {webhook['webhook_url']}")
Getting Event Instances
# Get instances for a date range
instances = client.get_event_instances(
event_id=event["id"],
from_date="2026-01-01",
to_date="2026-03-31"
)
# Get next instance
next_instance = client.get_next_event_instance(event["id"])
print(f"Next occurrence: {next_instance}")
Agenda & Search
# Get events and instances in a time window (agenda)
items = client.get_agenda(
start="2026-01-01T00:00:00Z",
end="2026-01-31T23:59:59Z",
calendar_ids=[calendar["id"]],
use_cache=True,
)
for item in items:
print(item["event"]["name"], item["instances"])
# Fuzzy search events by name
results = client.search_events(
q="team meeting",
start="2026-01-01T00:00:00Z",
end="2026-03-31T23:59:59Z",
limit=20,
include_instances=True,
)
for item in results:
print(item["event"]["name"], item.get("score"), item.get("instances"))
Error Handling
The SDK raises specific exceptions for different error types:
from anymoment import (
AuthenticationError,
NotFoundError,
ValidationError,
ServerError,
)
try:
calendar = client.get_calendar("invalid-id")
except NotFoundError:
print("Calendar not found")
except AuthenticationError:
print("Authentication failed - please login again")
except ValidationError as e:
print(f"Validation error: {e.message}")
except ServerError as e:
print(f"Server error: {e.message}")
Token Management
Tokens are automatically stored encrypted in ~/.anymoment/tokens.json using machine-specific encryption. The SDK handles:
- Automatic token refresh on expiration
- Multi-host token storage
- Secure encryption using Fernet
Development
Running Tests
# Install development dependencies
pip install -e ".[cli]"
pip install pytest pytest-mock pytest-cov build twine
# Run tests
pytest
# Run with coverage
pytest --cov=anymoment --cov-report=html
Building Distribution
# Install build tools
pip install build twine
# Build distributions
python -m build
# Check distributions
twine check dist/*
License
MIT License - see LICENSE file for details.
Support
- Python SDK & CLI docs: https://anymoment.sineways.tech/anymoment-python/docs
- AnyMoment docs: https://docs.anymoment.ai
- API Base URL: https://api.anymoment.sineways.tech
- Issues: https://github.com/SinewaysTechnology/anymoment-python/issues
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file anymoment-1.0.0.tar.gz.
File metadata
- Download URL: anymoment-1.0.0.tar.gz
- Upload date:
- Size: 28.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ff8718791e7212bc4882ca1d24ff2547d5700582d2543672299b96402a1d461
|
|
| MD5 |
33a2f4600cfaa1ba0836549c73cb29ed
|
|
| BLAKE2b-256 |
70bf188c982fdcdcaebb0a111838f9216d184073f6174b664e09b5e16595717b
|
Provenance
The following attestation bundles were made for anymoment-1.0.0.tar.gz:
Publisher:
workflow.yml on SinewaysTechnology/anymoment-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anymoment-1.0.0.tar.gz -
Subject digest:
4ff8718791e7212bc4882ca1d24ff2547d5700582d2543672299b96402a1d461 - Sigstore transparency entry: 992479051
- Sigstore integration time:
-
Permalink:
SinewaysTechnology/anymoment-python@0386381954ec93e3433f32355a2872686a758b3d -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/SinewaysTechnology
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@0386381954ec93e3433f32355a2872686a758b3d -
Trigger Event:
push
-
Statement type:
File details
Details for the file anymoment-1.0.0-py3-none-any.whl.
File metadata
- Download URL: anymoment-1.0.0-py3-none-any.whl
- Upload date:
- Size: 22.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
133b0c4e80e6053deda64e3ed291c4aa8a31261bf8d412f71e8f4014ab69fe31
|
|
| MD5 |
4085fa965154450e8730a6f9bfebe5e7
|
|
| BLAKE2b-256 |
a436e86548472bc5838010f44a376ea11085b4ef8020279f234b5623b690cc35
|
Provenance
The following attestation bundles were made for anymoment-1.0.0-py3-none-any.whl:
Publisher:
workflow.yml on SinewaysTechnology/anymoment-python
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
anymoment-1.0.0-py3-none-any.whl -
Subject digest:
133b0c4e80e6053deda64e3ed291c4aa8a31261bf8d412f71e8f4014ab69fe31 - Sigstore transparency entry: 992479060
- Sigstore integration time:
-
Permalink:
SinewaysTechnology/anymoment-python@0386381954ec93e3433f32355a2872686a758b3d -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/SinewaysTechnology
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
workflow.yml@0386381954ec93e3433f32355a2872686a758b3d -
Trigger Event:
push
-
Statement type: