> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squarecloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# v5 への移行

> squarecloud-api v4 から v5 への変更点: await ファサードを備えた同期クライアント、dataclass の代わりにプレーンな dict、リソースごとにグループ化されたメソッド、単一の例外クラス。メソッドごとの対応表付き。

v5 は全面的な書き直しです。SDK はデフォルトで同期型になり (`await` ファサード付き)、依存関係はゼロで、メソッドをリソースごとにグループ化し、プレーンな dict (`TypedDict`) を返し、単一の例外型を送出します。Square Cloud API の全 67 操作をカバーしています。

## 概要

| v4                                                                         | v5                                                                                                                         |
| -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `await client.x(...)`、非同期のみ                                                | `client.group.x(...)`、または `await async_client.group.x(...)`                                                                |
| 凍結された dataclass (`status.ram`)                                             | `TypedDict`、つまりプレーンな dict (`status['ram']`)。未知のフィールドは `TypeError` を送出せずに保持されます                                             |
| `Application` オブジェクト (`app.start()`、`app.cache`)                           | プレーンなデータと ID: `client.apps.start(app_id)`。キャッシュはありません                                                                      |
| 約 25 個の例外クラス (`NotFoundError`、`TooManyRequests`、`FewMemory` など)            | `.status`、`.code`、`.message`、`.method`、`.path` (`'/v2/...'`)、`.cause` を持つ `SquareCloudAPIError`                            |
| `squarecloud.File(path)`                                                   | パス、`bytes`、バイナリファイルオブジェクトを直接渡します                                                                                           |
| 位置引数による省略可能な引数                                                             | 省略可能な修飾引数はキーワード専用 (`status(id, raw=True)`、`commit(id, file, path=...)`、`databases.create(name, type=, version=, memory=)`) |
| リクエストリスナー (`@client.on_request`)、キャプチャリスナー、`avoid_listener`、`update_cache` | 削除。`squarecloud` [ロガー](/ja/sdks/py/client#ロギング) (DEBUG) またはカスタムの [`transport=`](/ja/sdks/py/client#カスタムトランスポート) を使ってください   |
| `aiohttp` と `typing-extensions` への依存                                       | なし                                                                                                                         |
| Python `>=3.13,<3.15`                                                      | Python `>=3.11`、上限なし                                                                                                       |

## 初期化とオプション

| v4                                                  | v5                                                                                                                                         |
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `squarecloud.Client(api_key, log_level=...)`        | `SquareCloud(api_key, *, base_url=BASE_URL, timeout=30.0, max_retries=2, transport=None, user_agent=...)`、または同じ引数の `AsyncSquareCloud(...)` |
| `log_level=` と、インポート時に付けられる色付きハンドラー                 | `NullHandler` 付きの `logging.getLogger('squarecloud')`。設定は自分で行います                                                                            |
| `aiohttp` のデフォルト (リクエストごとに 5 分、リアルタイムの読み取り間隔は 90 秒) | ソケット操作ごとの秒数で指定する `timeout`。保持される呼び出しと AI の呼び出しには 120 秒の下限があり、`timeout <= 0` ですべてのタイムアウトが無効になります                                            |
| リトライなし                                              | 安全な失敗のみを対象とする `max_retries` (2)。429 は決してリトライされません                                                                                          |
| ハードコードされた `User-Agent`                              | `user_agent=` でヘッダーを置き換えます (デフォルトは `squarecloud-sdk-py/<version>`)                                                                         |
| リクエストごとに新しいセッション                                    | `close()` または `with` / `async with` でプールされたキープアライブ接続を閉じます                                                                                  |

## メソッドごとの対応

| 旧 (v4 `Client`)                                                                        | 新 (v5 `SquareCloud`)                                                                 | 備考                                                                                                                                                                                                      |
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `user()`                                                                               | `account.me()['user']`                                                               | `me()` は `applications` と `databases` も返します                                                                                                                                                             |
| `all_apps()`                                                                           | `account.me()['applications']`                                                       |                                                                                                                                                                                                         |
| `app(app_id)`                                                                          | `apps.get(app_id)`                                                                   | `GET /apps/{id}` になり、workspace の ID `'<appId>-<workspaceId>'` でも動作します                                                                                                                                   |
| `user_snapshots(scope)`                                                                | `account.snapshots(*, scope=None)`                                                   | `scope` はキーワード専用。各項目は API の `version_id` と署名付き `url` を持ちます                                                                                                                                              |
| `service_status()`                                                                     | `service.status()`                                                                   |                                                                                                                                                                                                         |
| `upload_app(File(path))`                                                               | `apps.create(path)`                                                                  | ディスクからストリーミングします。`AppCreated` を返します (`domain` は Web サイトの完全なホストで、`subdomain` はありません)                                                                                                                     |
| `delete_app(id)`                                                                       | `apps.delete(id)`                                                                    | `None` を返します                                                                                                                                                                                            |
| `all_apps_status()`                                                                    | `apps.status_all(*, workspace_id=None)`                                              | 停止中のアプリも除外されなくなりました                                                                                                                                                                                     |
| `app_status(id)`                                                                       | `apps.status(id, *, raw=False)`                                                      | `raw=True` (キーワード専用) で数値を返します                                                                                                                                                                           |
| `start_app` / `stop_app` / `restart_app`                                               | `apps.start` / `apps.stop` / `apps.restart`                                          | `None` を返します                                                                                                                                                                                            |
| `get_logs(id)`                                                                         | `apps.logs(id)`                                                                      | `str` を返します                                                                                                                                                                                             |
| `app_metrics(id)`                                                                      | `apps.metrics(id)`                                                                   |                                                                                                                                                                                                         |
| `realtime(id)` (各 `data:` 行の非同期ジェネレーター。可能な場合は JSON としてデコード)                            | `apps.realtime(id)`                                                                  | 生の `data` テキストを持つ `{'event', 'data', 'id'}` のイテレーター。ログには `stream`/`line`、ステータスイベントにはマージされた `status` が加わります。自動的に再接続します (動作の変更を参照)。ストリームには読み取りタイムアウトがないため (v4 はデータなしで 90 秒経つと諦めていました)、`close()` で停止してください |
| `all_domains()`                                                                        | `apps.domains()`                                                                     |                                                                                                                                                                                                         |
| `load_balancers()`                                                                     | `apps.load_balancers()`                                                              |                                                                                                                                                                                                         |
| `commit(id, File(path))`                                                               | `apps.commit(id, file, *, path=None, filename=None)`                                 | キーワード専用の `path` = 保存先ディレクトリ。`filename` は zip 以外のファイルの名前 (`bytes` のデフォルトは `commit.zip`)                                                                                                                  |
| `github_integration(id, access_token)`                                                 | `apps.deploys.set_webhook(id, access_token)`                                         |                                                                                                                                                                                                         |
| `last_deploys(id)`                                                                     | `apps.deploys.list(id)`                                                              | イベントには `source`、`branch`、`files` が含まれます。失敗した deploy は `state='error'` と `code`、`message` で終わります                                                                                                         |
| `current_app_integration(id)`                                                          | `apps.deploys.current(id)`                                                           | webhook の文字列ではなく `{'app'?, 'webhook'?}` を返します                                                                                                                                                           |
| `get_app_envs` / `set_app_envs` / `overwrite_app_envs` / `delete_app_envs`             | `apps.envs.get` / `set` / `replace` / `delete`                                       |                                                                                                                                                                                                         |
| `clear_app_envs(id)`                                                                   | `apps.envs.replace(id, {})`                                                          |                                                                                                                                                                                                         |
| `app_files_list(id, path)`                                                             | `apps.files.list(id, path=None)`                                                     | エントリは API の `FileEntry` です (計算された `path`/`app_id` はありません)。存在しないディレクトリは `[]` を返す代わりに 404 `FILE_NOT_FOUND` を送出し、ブロックされたディレクトリは 403 `BLOCKED_PATH` になります                                                   |
| `read_app_file(id, path)` → `BytesIO`                                                  | `apps.files.read(id, path)` → `bytes`                                                | base64 エンコード (`?encoding=base64`) で取得してデコードします。10 MB を超えると 413 `FILE_TOO_LARGE`                                                                                                                         |
| `create_app_file(id, File(...), path)`                                                 | `apps.files.write(id, path, content)`                                                | `str` はテキストとして、`bytes` は base64 エンコードで送信されます (バイナリセーフ)。パスはそのまま送信されます (余分な `/` は付きません)。空の内容 (`''` または `b''`) は空のファイルを作成します                                                                               |
| `move_app_file(id, origin, dest)`                                                      | `apps.files.move(id, path, to)`                                                      |                                                                                                                                                                                                         |
| `delete_app_file(id, path)`                                                            | `apps.files.delete(id, path)`                                                        |                                                                                                                                                                                                         |
| `snapshot(id)` → `Snapshot`                                                            | `apps.snapshots.create(id)`                                                          | 202 の場合は例外を送出せずに `{'pending': True}` を返します。その後は `list` をポーリングし、再作成は決してしないでください                                                                                                                          |
| `all_app_snapshots(id)`                                                                | `apps.snapshots.list(id)`                                                            | 各項目は API の `version_id` と署名付きダウンロード `url` を、送られたまま持ちます                                                                                                                                                  |
| `restore_snapshot('app', id, snapshot_id, version_id)`                                 | `apps.snapshots.restore(id, name, version_id)`                                       | `list` の項目の `name` と `version_id`                                                                                                                                                                       |
| `restore_snapshot('database', id, ...)`                                                | `databases.snapshots.restore(id, name, version_id)`                                  | `list` の項目の `name` と `version_id`                                                                                                                                                                       |
| `Snapshot.download(path)`                                                              | `client.download_snapshot(url, dest)`                                                | zip そのものをストリーミングします (v4 は別の zip で包んでいました)                                                                                                                                                               |
| `domain_analytics(id, start=, end=, ...)`                                              | `apps.network.analytics(id, start, end, *, country=, ...)`                           | `start`/`end` は API で必須です。フィルターはキーワード専用です                                                                                                                                                               |
| `network_errors(id, start, end, include_4xx)` / `network_logs` / `network_performance` | `apps.network.errors(id, start, end, *, include_4xx=False)` / `logs` / `performance` | `analytics`、`errors`、`performance` はデータのない期間では `None` を返します                                                                                                                                             |
| `dns_records(id)`                                                                      | `apps.network.dns(id)`                                                               |                                                                                                                                                                                                         |
| `set_custom_domain(id, custom_domain)`                                                 | `apps.network.set_domain(id, domain)`                                                | v4 はボディを送信していませんでした                                                                                                                                                                                     |
| `purge_cache(id)`                                                                      | `apps.network.purge_cache(id)`                                                       |                                                                                                                                                                                                         |
| `link_github_app(id, repository_name, repository_branch)`                              | `apps.deploys.link_github_app(id, repository, branch)`                               | API キーで動作するようになりました (スコープ `apps:deploy`)。生の dict ではなく `LinkedRepository` (`{id, full_name, branch}`) を返します。GitHub App のインストールがない場合は 403 `GITHUB_NOT_CONNECTED`                                          |
| `unlink_github_app(id)`                                                                | `apps.deploys.unlink_github_app(id)`                                                 | `None` を返します。何も連携されていない場合は 400 `GIT_NOT_CONFIGURED`                                                                                                                                                     |
| `create_database(name, memory, type, version=None)`                                    | `databases.create(name, type=, version=, memory=)`                                   | キーワード専用。`version` は必須です (`'8'` のようなメジャーバージョンでも可)                                                                                                                                                        |
| `get_database_info(id)`                                                                | `databases.get(id)`                                                                  |                                                                                                                                                                                                         |
| `edit_database(id, name, memory)`                                                      | `databases.update(id, name=, ram=)`                                                  | v4 は API が無視する `memory` を送信していました                                                                                                                                                                       |
| `delete_database` / `start_database` / `stop_database`                                 | `databases.delete` / `start` / `stop`                                                |                                                                                                                                                                                                         |
| `get_database_status(id)`                                                              | `databases.status(id, *, raw=False)`                                                 |                                                                                                                                                                                                         |
| `all_databases_status()`                                                               | `databases.status_all()`                                                             |                                                                                                                                                                                                         |
| `database_metrics(id)`                                                                 | `databases.metrics(id)`                                                              |                                                                                                                                                                                                         |
| `get_database_certificate(id)` → `Certificate`                                         | `databases.certificate(id)` → base64 の `str`                                         | `base64.b64decode(...)` で PEM が得られます                                                                                                                                                                    |
| `reset_database_password(id)`                                                          | `databases.reset_credentials(id, 'password')`                                        | 新しいパスワードを返します                                                                                                                                                                                           |
| `reset_database_certificate(id)`                                                       | `databases.reset_credentials(id, 'certificate')`                                     | `''` を返します                                                                                                                                                                                              |
| `all_database_snapshots(id)` / `database_snapshot(id)`                                 | `databases.snapshots.list(id)` / `create(id)`                                        | アプリと同様に、各項目は `version_id` と `url` を持ちます                                                                                                                                                                 |
| `create_workspace(name)`                                                               | `workspaces.create(name)`                                                            | 1 回のリクエストで `{id, name}` を返します                                                                                                                                                                           |
| `all_workspaces()` / `get_workspace(id)`                                               | `workspaces.list()` / `workspaces.get(id)`                                           | v4 は各アプリの `id` を複合形式 `'<appId>-<workspaceId>'` に書き換えていました。v5 は API の素の ID を返すため、自分で組み立ててください: `f"{app['id']}-{workspace['id']}"`                                                                        |
| `delete_workspace` / `leave_workspace`                                                 | `workspaces.delete` / `workspaces.leave`                                             |                                                                                                                                                                                                         |
| `add_member_to_workspace(ws, invite_code, permissions)`                                | `workspaces.members.add(ws, code, group)`                                            |                                                                                                                                                                                                         |
| `modify_member_permissions(ws, user_id, permissions)`                                  | `workspaces.members.update(ws, member_id, group)`                                    |                                                                                                                                                                                                         |
| `remove_member_from_workspace(ws, user_id)`                                            | `workspaces.members.remove(ws, member_id)`                                           |                                                                                                                                                                                                         |
| `get_invite_code()`                                                                    | `workspaces.members.invite_code()`                                                   |                                                                                                                                                                                                         |
| `add_app_to_workspace` / `remove_app_from_workspace`                                   | `workspaces.apps.add` / `workspaces.apps.remove`                                     |                                                                                                                                                                                                         |
| —                                                                                      | `ai.chat(request)`                                                                   | 新規。`request` は OpenAI 形式のボディです (`{'messages': [...], 'model': ...}`)                                                                                                                                    |
| `client.api_key`                                                                       | 削除                                                                                   | キーへの参照は自分で保持してください                                                                                                                                                                                      |
| `on_request(endpoint)`、`Application.capture(endpoint)`                                 | 削除                                                                                   | [概要](#概要)のリスナーの行を参照してください                                                                                                                                                                               |
| `squarecloud.utils.ConfigFile`                                                         | 削除                                                                                   | `squarecloud.app` ファイルは自分で書いてください (`KEY=value` の行)                                                                                                                                                      |

`Application` のメソッドは、ID を渡す同じ呼び出しに対応します: `app.logs()` → `client.apps.logs(app.id)`、`app.files_list(path)` → `client.apps.files.list(app.id, path)` など。

## 型

レスポンスは `squarecloud.types` にある `TypedDict` で、JS と Go の SDK と同じ名前が付いています: `Account`、`User`、`Plan`、`AppSummary`、`DatabaseSummary`、`App`、`AppCreated`、`StatusListItem`、`RuntimeStats`、`MetricPoint`、`AppDomain`、`LoadBalancers`、`DeployEvent`、`DeployCurrent`、`DeployRepository`、`LinkedRepository`、`EnvVars`、`FileEntry`、`Snapshot`、`SnapshotCreated`、`SnapshotScope`、`AnalyticsFilters`、`NetworkAnalytics`、`NetworkErrors`、`NetworkLog`、`NetworkPerformance`、`DNSRecord`、`Database`、`DatabaseCreated`、`DatabaseType`、`Workspace`、`WorkspaceCreated`、`WorkspaceGroup`、`ServiceStatus`、`ServiceEntry`、`ChatRequest`、`ChatMessage`、`ChatCompletion`、`RealtimeEvent`、`RealtimeStatus`。これらは v4 の `data/*` の dataclass (`UserData`、`StatusData`、`AppData` など) を置き換えます。`squarecloud.Response` はトランスポートのレスポンスのプロトコルになりました ([カスタムトランスポート](/ja/sdks/py/client#カスタムトランスポート)を参照)。変更系が返していた v4 の `Response` はなくなり、変更系は `None` を返します。

## エラー

| v4                                                                | v5                                                                                                     |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `AuthenticationFailure`                                           | `e.status == 401` (`ACCESS_DENIED`。期限切れのキーでも同様)                                                        |
| `NotFoundError`、`ApplicationNotFound`                             | `e.status == 404` (`APP_NOT_FOUND`、`WORKSPACE_NOT_FOUND` など)                                           |
| `BadRequestError` と `InvalidConfig` ファミリー                         | `e.status == 400`。`e.code` を確認してください                                                                   |
| `TooManyRequests`                                                 | `e.status == 429` (`RATE_LIMITED`、`KEEP_CALM`)                                                         |
| `FewMemory` (送出されることはありませんでした: API は `INSUFFICIENT_MEMORY` を送ります) | `e.code == 'INSUFFICIENT_MEMORY'`                                                                      |
| `InvalidDomain` (`REGEX_VALIDATION`。現在は送信されません)                   | `e.code == 'INVALID_DOMAIN'`                                                                           |
| 403/503 に対する `RequestError`                                       | `e.code` が `MISSING_SCOPE`、`RESOURCE_NOT_ALLOWED`、`BLOCKED_PATH`、`UPLOAD_BUSY` など                      |
| 漏れ出していた `aiohttp` の例外                                             | `e.status == 0`、`e.code` が `NETWORK_ERROR` または `TIMEOUT` (元の例外は `e.cause`)                             |
| —                                                                 | `FILE_TOO_LARGE` または `INVALID_ID` を伴う `e.status == 0`: ローカルチェックで、何も送信されていません                           |
| 漏れ出していたプロキシの HTML や JSON でないボディ                                   | 実際のステータスとメッセージ `HTTP <status>` を持つ `UNKNOWN_ERROR` (2xx の場合は `Invalid JSON in HTTP <status> response`) |

`str(e)` は `'<METHOD> <path>: HTTP <status> <CODE>: <message>'` です。ステータスが `0` の場合は `HTTP <status>` が、メッセージが空の場合は `: <message>` が省かれます。サーバーがコードしか送らなかった場合、`e.message` は `''` です。

## 動作の変更

* 省略可能な修飾引数はキーワード専用です: `account.snapshots(scope=)`、`apps.status_all(workspace_id=)`、`apps.status(id, raw=)`、`databases.status(id, raw=)`、`apps.commit(id, file, path=, filename=)`、`apps.network.errors(..., include_4xx=)`、`apps.network.analytics(...)` のフィルター、`databases.update(id, name=, ram=)`、`databases.create(name, type=, version=, memory=)`。`apps.files.list` の省略可能な `path` は位置引数のままです。
* 2xx の `{"status": "error"}` ボディは例外を送出します。アプリとデータベースの起動・停止の拒否は、コードのみを持つ 409 です (`CONTAINER_ALREADY_STARTED`、`ACTION_FAILED` など)。202 `SNAPSHOT_PROCESSING` は例外を送出せずに `{'pending': True}` を返します: `list` をポーリングし、`create` を再度呼び出さないでください。
* 設定されていない省略可能なクエリ値 (および `''`) は、送信されずに省かれます。
* 文字列の結果が `None` になることはありません: `reset_credentials(id, 'certificate')` と削除された webhook は `''` を返します。
* `apps.files.write` は `str` をテキストとして、`bytes` を base64 エンコードで送信します。空の内容は空のファイルを作成し、1 MiB を超える内容はタイムアウトなしで送信されます。`apps.files.read` は常に base64 を要求し、デコードされた `bytes` を返します。
* 存在しないディレクトリに対する `apps.files.list` は 404 `FILE_NOT_FOUND` を送出します。
* 503 `DATABASE_UNAVAILABLE` は変更が適用された後に発生することがあるため、`GET` でのみリトライされます。冪等な変更をリトライするかどうかは呼び出し側に委ねられます。
* リアルタイムのストリームは `{'event', 'data', 'id', ...}` のイベントを返し、5.5 秒に 1 回のオープンで連続最大 3 回まで再オープンし、オープンに失敗すると例外を送出します。

## 非同期

v4 は非同期のみでした。v5 では `SquareCloud` が同期型で、`AsyncSquareCloud` が `await` ファサードです。グループとメソッドは同じで、各呼び出しは `asyncio.to_thread` で実行されるため、イベントループがブロックされることはありません。リアルタイムのストリームは `async for` になり (読み取りスレッドがループにデータを渡します)、`async with` または `close()` で閉じます。

v4:

```python theme={"system"}
client = squarecloud.Client(key)
status = await client.app_status(app_id)
print(status.ram)
async for data in client.realtime(app_id):
    print(data)
```

v5:

```python theme={"system"}
async with squarecloud.AsyncSquareCloud(key) as client:
    status = await client.apps.status(app_id)
    print(status['ram'])
    async with client.apps.realtime(app_id) as stream:
        async for event in stream:
            print(event['data'])
```
