Metadata-Version: 2.4
Name: athena-openpyxl
Version: 0.1.0
Summary: Drop-in replacement for openpyxl that writes to Athena's Keryx-backed spreadsheet Y.Docs
Project-URL: Homepage, https://github.com/Athena-Intel/demo-app-monorepo/tree/staging/xlsx-studio
Project-URL: Documentation, https://github.com/Athena-Intel/demo-app-monorepo/tree/staging/xlsx-studio/python-sdk
Project-URL: Issues, https://github.com/Athena-Intel/demo-app-monorepo/issues
Author-email: Athena Intelligence <engineering@athenaintelligence.ai>
License-Expression: MIT
Keywords: excel,keryx,openpyxl,pycrdt,sdk,spreadsheet,xlsx
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Spreadsheet
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: cryptography>=41.0
Requires-Dist: httpx>=0.27
Requires-Dist: pycrdt>=0.12.0
Requires-Dist: websockets>=12.0
Provides-Extra: dev
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.1; extra == 'dev'
Description-Content-Type: text/markdown

# athena-openpyxl

openpyxl-shaped Python SDK that writes directly to Athena's Keryx-backed spreadsheet Y.Docs. No HTTP middleware — mirrors `athena-python-docx`.

## Quick start

```python
from openpyxl import Workbook

with Workbook("asset_abc123") as wb:   # opens Keryx session, runs initial sync
    ws = wb.active
    ws["A1"] = "Hello"
    ws["A2"] = 42
    ws["A3"] = "=SUM(A2)"
    wb.save()                          # flushes pending updates to Keryx
```

## Environment

The SDK reads these env vars (Daytona-managed in production):

| Variable | Required | Notes |
|---|---|---|
| `KERYX_WS_URL` | ✓ | e.g. `wss://keryx-staging.athenaintel.com` |
| `ATHENA_WORKSPACE_ID` | ✓ | workspace routing segment |
| `KERYX_COLLAB_TOKEN` | one of | pre-minted JWT (preferred — Daytona injects this) |
| `KERYX_AUTH_PRIVATE_KEY` | one of | ECDSA P-384 JWK/PEM; used to sign locally for dev |
| `ATHENA_SERVICE_USER_ID` |   | `yuserid` JWT claim, defaults to `athena@athenaintel.com` |

## Install (development)

```bash
cd xlsx-studio/python-sdk
uv venv && uv pip install -e ".[dev]"
uv run pytest tests/
```

## Phase 2 scope (this release)

What works today:
- Opening a workbook by `asset_id`.
- Reading the sheets list from `sheetDataV3`.
- Single-cell reads and writes of strings / numbers / bools / formulas.
- Flushing via `wb.save()`; clean teardown via `wb.close()` or context-manager exit.

Raises `UnsupportedFeatureError` (clearly scoped, not silently no-op):
- Cell formatting: `font`, `fill`, `alignment`, `number_format`.
- Range accessors: `ws['A1:C3']`, `iter_rows`, `append`.
- Structural mutations: `wb.create_sheet`, `wb.remove`, `ws.title = x`.
- Merges, freeze panes, column/row dimensions.

All of those land in Phase 3 (see [xlsx-studio/CLAUDE.md](../CLAUDE.md)).

## Architecture

```
Agent code (openpyxl idiom)
    ↓
Workbook / Worksheet / Cell  (sync facade)
    ↓  _batching.run_sync → persistent background event loop thread
Session  (pycrdt Doc + Keryx connection)
    ↓  _keryx_client: ECDSA P-384 JWT + y-websocket sync protocol
Keryx  ←→  Olympus (@rowsncolumns/y-spreadsheet renderer)
  (same Y.Doc; room = "{workspace}/{asset_id}")
```

- `_keryx_client.py` — ECDSA P-384 JWT signing, y-websocket sync step1/step2/update frames. Ported down from `agora/agora/services/keryx/client.py`, minus retry/metrics/awareness.
- `_batching.py` — sync→async bridge, one persistent event loop. Ported from `docx-studio/python-sdk/docx/_batching.py`.
- `_session.py` — `Session` class owning the pycrdt `Doc` + WebSocket; exposes `set_cell_value` / `get_cell_value` / `list_sheets`.
- `cell.py`, `worksheet.py`, `workbook.py` — openpyxl-shaped sync facade that routes through `Session`.

## Publishing

```bash
bash ../scripts/publish-python-sdk.sh 0.1.0
```
