Metadata-Version: 2.4
Name: discordbase
Version: 0.1.0
Summary: Experimental Discord-backed datastore for small Python apps.
Author: Kantai235
License-Expression: MIT
Project-URL: Homepage, https://github.com/Kantai235/DiscordBase
Project-URL: Repository, https://github.com/Kantai235/DiscordBase
Project-URL: Issues, https://github.com/Kantai235/DiscordBase/issues
Project-URL: Documentation, https://github.com/Kantai235/DiscordBase#readme
Keywords: discord,database,datastore,discord-bot,crud
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.25
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == "dev"
Requires-Dist: python-dotenv>=1.0; extra == "dev"
Requires-Dist: twine>=5.0; extra == "dev"
Dynamic: license-file

# DiscordBase

DiscordBase 是一套實驗性的 Python 套件，使用 Discord 伺服器作為小型資料儲存層。

狀態：本機原型，已具備真實 Discord smoke test 與 CRUD 整合測試。

> DiscordBase 刻意維持保守而小巧。它適合 demo、Discord bot 設定、低流量資料集，以及需要人工檢閱資料狀態的場景。它不是 PostgreSQL、SQLite、Redis，也不是需要強一致性或高寫入吞吐量的正式環境資料庫替代品。

## 核心概念

```text
Discord 伺服器 = database
Discord 文字頻道 = table
Discord 訊息 = row document
```

DiscordBase 的目標不是取代傳統資料庫，而是提供一個可觀察、低流量、容易人工檢查的資料儲存方式。Table 頻道裡的一則 Discord 訊息就是一筆目前資料；更新資料會編輯那則訊息，刪除資料會刪掉那則訊息。

## 伺服器結構

```text
DiscordBase
  # discordbase-catalog
  # users
  # posts
  # settings
```

`discordbase-catalog` 是中繼資料頻道。它負責記錄邏輯 table 名稱、Discord channel ID、primary key 欄位，以及可選的 schema 欄位型態。Table 的真正身分以 channel ID 為準，而不是可被手動改名的頻道名稱。

## 安裝

PyPI 發佈後可直接安裝：

```bash
python3 -m pip install discordbase
```

第一次 PyPI 發佈前，或想安裝 GitHub 上最新版本時，可以用：

```bash
python3 -m pip install git+https://github.com/Kantai235/DiscordBase.git
```

若要從本 repo 以 editable 模式開發：

```bash
python3 -m pip install -e .
```

若要讓範例與工具自動讀取 `.env`：

```bash
python3 -m pip install -e ".[dev]"
```

## 快速範例

```python
from discordbase import DiscordBase

async with await DiscordBase.connect(token="...", guild_id="...") as db:
    await db.init()

    users = await db.table(
        "users",
        pk="id",
        schema={"id": "str", "name": "str"},
        create=True,
    )

    await users.insert({"id": "u_1", "name": "Kantai"})
    row = await users.get("u_1")

    await users.patch("u_1", {"name": "Kai"})
    await users.delete("u_1")
```

目前實作是 REST-only，並且最適合單一 writer 使用。所有 Discord HTTP 呼叫都集中在 `rest.py`，遇到 429 rate limit 時會依 Discord 回傳的 `retry_after` 等待，而不是寫死路由限制。

## 訊息格式

DiscordBase 訊息預設會以 `DB1 ` 開頭。Catalog 頻道使用 metadata event：

```text
DB1 {"op":"table.create","name":"users","channel_id":"...","pk":"id","schema":{"id":"str","name":"str"}}
```

Table 頻道則直接存 row document：

```text
DB1 {"id":"u_1","name":"Kai"}
```

`DB1` 代表 DiscordBase protocol version 1。這個前綴讓讀取器可以忽略一般 Discord 聊天訊息，也讓同一個 Discord 伺服器能用不同 prefix 區分資料 namespace。

可以在連線時自定義新訊息的 prefix：

```python
async with await DiscordBase.connect(
    token="...",
    guild_id="...",
    event_prefix="KDB1",
) as db:
    users = await db.table("users", pk="id", schema={"id": "str"}, create=True)
```

如果要從既有 `DB1` 資料 migration 到新 prefix，可以同時讀取舊 prefix：

```python
async with await DiscordBase.connect(
    token="...",
    guild_id="...",
    event_prefix="KDB1",
    read_event_prefixes=("DB1",),
) as db:
    users = await db.table("users")
```

`event_prefix` 會用於新寫入訊息；`read_event_prefixes` 只影響讀取時額外接受哪些歷史前綴。

## 目前不做的事

- 不提供 SQL engine。
- 不提供跨 table transaction。
- 不保證強一致性的多 writer 寫入。
- 不建議儲存密碼、token 或敏感個資。
- 不支援高頻寫入。
- MVP 路徑不依賴 Message Content privileged intent。

## 文件導覽

- [使用教學](docs/tutorial.md)
- [架構說明](docs/architecture.md)
- [規範與限制](docs/limits.md)
- [MVP 規格](docs/mvp-spec.md)
- [研究紀錄](docs/research-notes.md)
- [測試伺服器設定](docs/test-server-setup.md)
- [發佈到 PyPI](docs/publishing.md)

## Smoke Test

確認 `.env` 指向拋棄式 Discord 測試伺服器後，可以執行：

```bash
python3 tools/discord_smoke.py
```

這會驗證 bot 能存取 guild、建立 DiscordBase category 與 catalog channel、用目前設定的 prefix 寫入一則 smoke metadata event，並透過 REST 讀回 bot 自己寫入的訊息內容。

依照 [AGENTS.md](AGENTS.md)，除非你明確要測真實 Discord，否則不要自動執行這個腳本。

## 開發與測試

執行不打 Discord 的單元測試：

```bash
python3 -m unittest discover -v
```

執行真實 Discord CRUD 整合測試：

```bash
DISCORDBASE_RUN_INTEGRATION=1 python3 -m unittest tests.test_integration_crud -v
```

CRUD 整合測試會使用 `.env` 指定的拋棄式測試伺服器，建立或載入 `crud-tests` table，寫入唯一 row message，讀取、編輯同一則訊息、刪除同一則訊息，最後確認 table 回到測試前的數量。

## 模組邊界

```text
discordbase/
  client.py   # 對外 DiscordBase class，負責 guild/category/catalog 協調
  rest.py     # Discord REST 非同步封裝與 429 retry
  catalog.py  # catalog 中繼資料 replay 與 table 對應
  schema.py   # table schema 正規化與 row 驗證
  table.py    # row CRUD API，insert/send、patch/edit、delete/delete message
  events.py   # DB1 prefix + JSON 編碼、解碼與訊息萃取
  errors.py   # 公開例外型別
```
