Metadata-Version: 2.4
Name: light-phone-api
Version: 0.1.1
Summary: Unofficial Python API for the Light Phone
Author-email: Alexis Garado <alexisgarado@proton.me>
Requires-Python: >=3.11
Requires-Dist: attrs>=22.2.0
Requires-Dist: httpx<0.29.0,>=0.23.0
Requires-Dist: keyring
Requires-Dist: mutagen
Requires-Dist: python-dateutil>=2.8.0
Description-Content-Type: text/markdown


# Light API/CLI/TUI

An unofficial, community-maintained API and CLI/TUI for managing music, notes, podcasts, and tools on Light devices.

This was made by reverse-engineering the API endpoints from the official dashboard. (I have obtained Light's blessing for this.)

> [!CAUTION]
> This is beta software and is **actively in development.** Bugs are expected, and bug reports are welcome!

> [!WARNING]
> Because this is an **unofficial** set of tools created through reverse-engineering, this could break at any time if Light decides to change the structure of their API.

## Installation

This repo bundles two separate packages `light-api` and `light-cli-tui`. Install whichever suits your needs.

From PyPI:

```
pip install light-phone-api
pip install light-phone-cli-tui
```

Nix users:

```
{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
    light.url = "github:garado/light";
  };

  outputs = { nixpkgs, light, ... }: {
    nixosConfigurations.YOURHOST = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      modules = [
        ({ pkgs, ... }: {
          environment.systemPackages = [
            light.packages.x86_64-linux.light-cli-tui
            light.packages.x86_64-linux.light-api
          ]
        }
      ];
    };
  };
}
```

## Authentication

This needs your Light email, password, and phone number to authenticate into the Light dashboard and operate on the correct device.

Three options:

```sh
# 1. Environment variable
# Assuming LIGHT_EMAIL, LIGHT_PASSWORD, LIGHT_PHONE_NUMBER are set (see .env.example)
light <command>

# 2. Command line
light --email=... --password=... --phone-number=... <command>

# 3. File
light --email-file=... --password-file=... --phone-number-file=... <command>
```

After the first login, your auth token will be cached. Tokens are good for 30 days.

## Getting started: CLI/TUI

**Note:** As is the case with the official Light dashboard, any changes made through these tools may take a few moments to propagate to the device.

### Music

#### Upload

```sh
# Upload tracks
# Overwrite existing matching tracks (match on file title metadata)
light music upload song1 song2 song3 --match-title-by metadata

# Upload tracks
# Overwrite existing matching tracks (match on filename)
light music upload song1 song2 song3 --match-title-by filename

# Upload tracks
# Don't overwrite existing tracks
light music upload --allow-duplicates song1 song2 song3
```

#### Delete

```sh
# Delete tracks
light music delete song

# Delete all tracks (multiple confirmation steps, don't worry)
light music delete-all
```

#### Sort

```sh
# Sort tracks by title (!!!)
light music sort title --asc
light music sort title --desc

# Sort tracks by artist
light music sort artist --asc
light music sort artist --desc

# Sort tracks by artist and album (!!!)
# (Track numbers not supported)
light music sort artist-album --asc
light music sort artist-album --desc
```

### Notes

```sh
# List all notes (with optional content preview)
light notes list
light notes list --content-preview

# List notes with file IDs (needed for `watch` cmd)
light notes list --id

# Create a new text note
light notes add "Shopping list" "eggs, milk, bread"
light notes add "Meeting notes" --file notes.txt  # copy contents from notes.txt

# Download all notes to a directory
# Text notes saved as .txt, audio notes as .m4a
light notes download ~/my-notes

# Watch a note for changes (polls every 5s, prints when updated_at changes)
# Useful for more advanced custom integrations (happy hacking!)
light notes watch <note-id>
```

### Podcasts

```sh
# Subscribe to a podcast by RSS feed URL
light podcast add https://feeds.simplecast.com/FO6kxYGj

# List followed podcasts
light podcast list

# Unfollow a podcast by title
light podcast delete "My Podcast"
```

### Tools

Available tools: `alarm album calculator calendar camera directions directory hotspot music notes podcasts timer`

```sh
light tools list

light tools add <tool>

light tools remove <tool>
```

### TUI

The TUI offers an easier way of managing music and notes.

```sh
# Launch
light tui
```

TUI-specific features:
- First-class support for Vim bindings
- Music
    - Reorder tracks individually or in visual block mode
    - Bulk edit track metadata
    - Bulk delete tracks
- Notes
    - Content preview for both text and audio notes
    - Press `e` to edit in `$EDITOR`

#### Music

| Key | Action |
|-----|--------|
| `j` / `k` | Navigate |
| `gg` / `G` | Jump to top / bottom |
| `J` / `K` | Move track up / down |
| `5J` / `5K` | Move track up / down by 5 |
| `v` | Enter visual mode (select a block) |
| `J` / `K` in visual | Move selected block up / down |
| `gg` / `G` in visual | Move selected block to top / bottom |
| `d` in visual | Delete selected tracks |
| `e` | Edit track metadata |
| `e` in visual | Bulk edit metadata (shared fields pre-filled) |
| `s` | Cycle sort mode |
| `/` | Search |
| `r` | Refresh |

#### Notes

| Key | Action |
|-----|--------|
| `j` / `k` | Navigate |
| `gg` / `G` | Jump to top / bottom |
| `Enter` | Load note content |
| `n` | New note (opens in `$EDITOR`) |
| `e` | Edit note content in `$EDITOR` |
| `R` | Rename note |
| `dd` | Delete note (with confirmation) |
| `y` | Copy content to clipboard |
| `p` | Play / stop audio note |
| `r` | Refresh |

#### Screenshots

<img height="600" alt="image" src="https://github.com/user-attachments/assets/6a98a91c-63e7-4673-8e37-91c280774ef8" />

<img height="600" alt="image" src="https://github.com/user-attachments/assets/10612e61-1dc3-4e4f-95d3-302d95f15bad" />


## Getting started: API

Minimal API usage examples are in [`examples/`](https://github.com/garado/light/tree/main/examples).

## Tests

### Unit tests

Unit tests use request playback with `respx`.

```py
# This will populate `tests/fixtures/` with the response JSON to test against
python scripts/capture_fixture.py

# Run tests
uv run pytest
```

### Smoke tests (TODO)

As this is an **unofficial** tool, it could break at any time if Light changes the API format. Smoke tests should be added and run regularly (home server nightly cronjob?) to catch any breaking API changes asap.

# Developer stuff

## Regenerate API from spec

The source of truth is the OpenAPI JSON. Python API bindings are automatically generated from that JSON using `openapi-python-client`.

```
cd light_api
openapi-python-client generate --path openapi-spec.json
# this will generate open-api-specification-client (kebab case)
# delete the existing open_api_specification_client contents and copy the kebab-case dir contents to the snake-case dir
```
