Skip to main content

pygemstone

PyPI Python License

Standalone Python library for Gemstone Lights permanent-Christmas-light controllers.

Gemstone's mobile app talks to an AWS Amplify backend (Cognito + API Gateway + AppSync) in us-west-2, so this library is essentially:

  • a Cognito SRP login wrapper (delegated to pycognito)
  • an aiohttp REST client for the public endpoints that control the lights (/deviceControl/onState, /deviceControl/play/pattern, etc.)

Status: alpha — under active reverse-engineering of the iOS com.gemstone.lights app. APIs will change.

Features

  • Async login / token refresh (via Cognito User Pool SRP)
  • Account & home group:
    • account_profile() — your user profile
    • homegroups() / homegroup_users(hg)
    • invitations(status="pending") — pending invites (raw dict; schema unknown)
  • Devices:
    • devices(hg) — list controllers
    • device_state(id) / set_on_state(id, on) / play_pattern(id, p)
    • device_groups(hg) — multi-device zones (raw dict; schema unknown)
  • Pattern catalogue:
    • folders() / folder_patterns(page=N) / save_folder(id, body)
    • swatches() — colour palettes
    • downloadable_folders(page=N) / downloadable_patterns(page=N) — Gemstone-curated catalogue
  • Autopilot / scheduling:
    • events_settings(hg) — daily on/off window + enabled categories
    • subscribed_events(hg, page=N) — date-bound holiday/event subscriptions
    • events_categories() — full catalogue of holiday / sport / event categories
  • Timers:
    • timers_by_homegroup(hg) — scheduled on/off timers with optional pattern
  • Misc:
    • announcements() — in-app announcements

A note on AppSync (real-time)

The library ships an AppSync GraphQL HTTP + WebSocket transport (pygemstone.appsync.AppSyncClient), but two iOS-app captures show the official app never opens a GraphQL connection — only unauthenticated /ping healthchecks. State updates propagate via REST polling of /deviceControl/currentlyPlaying. The AppSync auth scheme is therefore unknown and the transport is currently un-runnable against the real backend; it's kept as scaffolding for if Gemstone ever flips real-time on.

Planned

  • Cognito global sign-out (currently only clears local tokens)
  • Schedule/event subscribe + unsubscribe mutations
  • Timer create / update / delete (only list is currently captured)

Installation

pip install pygemstone

Usage

import asyncio
from pygemstone import GemstoneClient

async def main():
    async with GemstoneClient("you@example.com", "...") as gc:
        await gc.login()
        for group in await gc.homegroups():
            print(group.name)
            for device in await gc.devices(group.id):
                state = await device.refresh()
                print(" ", device.name, "on" if state.on_state else "off")
                if not state.on_state:
                    await device.turn_on()

asyncio.run(main())

CLI

A small CLI is provided for manual testing:

python -m pygemstone login
python -m pygemstone list
python -m pygemstone state <DEVICE_ID>
python -m pygemstone on <DEVICE_ID>
python -m pygemstone off <DEVICE_ID>

Credentials are read from GEMSTONE_EMAIL / GEMSTONE_PASSWORD env vars, or a .env file in the working directory.

Security note

Like the other Amplify-based IoT services, Gemstone's Cognito user pool id and app client id are public values that any decompiled IPA / packet capture exposes — they're shipped in const.py as defaults. Do not commit credential files, JWT tokens, or mitmproxy .flows files.

Reverse-engineering notes

The endpoint catalogue was derived from a mitmproxy --mode wireguard capture of the official iOS app. Notes are kept private (the capture contains a live Cognito session); the public endpoint shape is in const.py.

License

MIT — see LICENSE.

Metadata

Release files for pygemstone 0.0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pygemstone 0.0.5
File Size Uploaded Provenance Actions
pygemstone-0.0.5.tar.gz 37.1 kB With provenance Details for pygemstone-0.0.5.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pygemstone 0.0.5
File Interpreter ABI Platform Actions
pygemstone-0.0.5-py3-none-any.whl Python 3 none any Details for pygemstone-0.0.5-py3-none-any.whl

Total release size: 64.5 kB

Release files / pygemstone-0.0.5.tar.gz

Download URL pygemstone-0.0.5.tar.gz
Size 37.1 kB
Tags Source
SHA-256 checksum
How to use checksums
fae55acc7f57ec99c507c77aa3bfc9dbe87f45b4d35931c74b9a105da07a8f3a
BLAKE2b-256 checksum
How to use checksums
0903896d7254df556ff58edaa492bc5e2f2866b562022ff1f0e7ceb1921ff9c1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Release files / pygemstone-0.0.5-py3-none-any.whl

Download URL pygemstone-0.0.5-py3-none-any.whl
Size 27.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a0d83f37a7ab040eaef0481c3da5b340a9fcf03b8471cd320f1a9e08104edd2d
BLAKE2b-256 checksum
How to use checksums
159588b27d24d345ea2f0f4fa1234ab2076ebacecd7fe4a1f42f0a39925b1e09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

Security for pygemstone 0.0.5

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for pygemstone-0.0.5.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.

Transparency log

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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page