pygemstone
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.lightsapp. APIs will change.
Features
- Async login / token refresh (via Cognito User Pool SRP)
- Account & home group:
account_profile()— your user profilehomegroups()/homegroup_users(hg)invitations(status="pending")— pending invites (raw dict; schema unknown)
- Devices:
devices(hg)— list controllersdevice_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 palettesdownloadable_folders(page=N)/downloadable_patterns(page=N)— Gemstone-curated catalogue
- Autopilot / scheduling:
events_settings(hg)— daily on/off window + enabled categoriessubscribed_events(hg, page=N)— date-bound holiday/event subscriptionsevents_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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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 logRelease 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 logSecurity 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.
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 logA 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.