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

# REPLノード

> ワークフロー内で直接Pythonコードを実行します。

**REPL**（Read-Eval-Print Loop）ノードを使用すると、AIワークフローの一部としてカスタムコードスニペットを実行できます。これは、標準ノードではカバーされないデータ変換、計算、またはカスタムロジックに強力です。

<img src="https://mintcdn.com/gidrai/r1bOdD2EuKA88Eme/images/ai-studio/repl-clean-workflow.png?fit=max&auto=format&n=r1bOdD2EuKA88Eme&q=85&s=06c68b2c07ca02560b5f10bb310c056e" alt="ワークフロー内のREPLノード" width="1200" height="800" data-path="images/ai-studio/repl-clean-workflow.png" />

## 概要

REPLノードは次の場合に使用します：

* ノード間でデータを変換またはフォーマットする
* 数学的計算を実行する
* 文字列を解析または操作する
* カスタムビジネスロジックを実装する
* API応答を構造化形式に処理する

## 設定

<img src="https://mintcdn.com/gidrai/r1bOdD2EuKA88Eme/images/ai-studio/repl-config-top.png?fit=max&auto=format&n=r1bOdD2EuKA88Eme&q=85&s=204f0e9bebac0466c73294ba4e409536" alt="REPL設定" style={{ width: '300px' }} width="1200" height="800" data-path="images/ai-studio/repl-config-top.png" />

### 基本設定

* **タイトル**: ノードのわかりやすい名前（例：「合計の計算」、「応答のフォーマット」）。
* **説明**: 将来の参照用にコードの動作を記録します。

## ランタイム環境

REPLノードは、安全なサンドボックス環境で実行されます。以下は、サポートされている関数、ライブラリ、および特定の制限事項です。

### コア要件

* **必須のメイン関数**: コードには `def main():` 関数を含める必要があります。
* **保護された反復**: `for` および `while` ループはサポートされていますが、無限実行を防ぐために監視されています。

### 入力コード

Pythonスクリプトを記述するコードエディタです。コードからは以下を利用できます：

* **ワークフロー変数**: `{{variable_name}}` 構文を使用して、前のノードからの変数にアクセスします。
* **組み込み関数**: データ処理用の標準Pythonライブラリ。

### 入力と出力

* **入力変数セレクター**: 前のノードからの特定の変数をマップして、コードで使用します。
* **出力**: ノードは、出力ハンドルを介してコード実行の結果を下流ノードに渡します。

<Tip>
  **例**: JSON応答を解析し、特定のフィールドを抽出します：

  ```python theme={null}
  import json
  data = json.loads({{api_response}})
  result = data.get('items', [])[:5]  # 最初の5項目を取得
  ```
</Tip>

### 組み込み関数

データ操作には標準のPython組み込み関数を使用できます：

* **コレクションヘルパー**: `list`, `dict`, `tuple`, `set`, `enumerate`, `reversed`
* **数学と論理**: `max`, `min`, `sum`, `abs`, `all`, `any`
* **ユーティリティ**: `type`

### サポートされているライブラリ

以下の標準ライブラリはプリインストールされており、安全にインポートできます：

* **データとフォーマット**: `json`, `xml`, `base64`, `pandas`
* **ネットワーキング**: `requests`
* **時間と日付**: `datetime`, `time`
* **ユーティリティ**: `re` (正規表現), `hashlib`, `hmac`, `secrets`, `typing`
* **データベース**: `sqlalchemy`, `sqlalchemy.orm`, `psycopg2`

### GCS ヘルパー関数

組み込みの Google Cloud Storage（GCS）ヘルパー関数を使用すると、現在のGIDR用ストレージバケット内のファイルを読み取り、書き込み、一覧表示、削除できます。これらの関数は実行時にサンドボックスへ注入されるため、インポートは不要です。

各GIDRには専用で分離された Google Cloud Storage バケットがあります。パスはそのGIDRのルート（`gidr/files/{gidr_id}/`）からの相対パスです。たとえば `reports/2026/july.csv` のように、サブフォルダへファイルを書き込めます。

あるGIDRが書き込んだファイルには、他のGIDRからアクセスできません。`../other-gidr/file.txt` のようなパストラバーサルはブロックされます。

#### `gidr_write_gcs`

コンテンツをGCSのファイルへアップロードします。ファイルが存在しない場合は作成し、存在する場合は上書きします。

```python theme={null}
gidr_write_gcs(path, content, content_type='application/octet-stream')
```

| パラメータ          | 型                 | 必須  | 説明                                                                                             |
| -------------- | ----------------- | --- | ---------------------------------------------------------------------------------------------- |
| `path`         | `str`             | はい  | `reports/july.csv` など、GIDRルートからの相対ファイルパス。                                                      |
| `content`      | `str` または `bytes` | はい  | アップロードするファイルの内容。                                                                               |
| `content_type` | `str`             | いいえ | MIMEタイプ。デフォルトは `application/octet-stream`。`text/plain`、`text/csv`、`application/json` などを使用します。 |

**戻り値:** `{"status": 200, "path": "reports/july.csv"}`

**例外:** パスが空または無効な場合は `ValueError`。GCSへのアップロードに失敗した場合は `RuntimeError`。

```python theme={null}
def main():
    result = gidr_write_gcs(
        'reports/july.csv',
        'date,value\n2026-07-01,100',
        content_type='text/csv'
    )
    return result
```

#### `gidr_read_gcs`

GCSからファイルの内容をダウンロードします。

```python theme={null}
gidr_read_gcs(path)
```

| パラメータ  | 型     | 必須 | 説明                  |
| ------ | ----- | -- | ------------------- |
| `path` | `str` | はい | GIDRルートからの相対ファイルパス。 |

**戻り値:** ファイルの内容を文字列として返します。

**例外:** パスが空または無効な場合は `ValueError`。ファイルが存在しない場合は `RuntimeError`（404）。

```python theme={null}
def main():
    content = gidr_read_gcs('reports/july.csv')
    return content
```

#### `gidr_delete_gcs`

GCSからファイルを削除します。

```python theme={null}
gidr_delete_gcs(path)
```

| パラメータ  | 型     | 必須 | 説明                  |
| ------ | ----- | -- | ------------------- |
| `path` | `str` | はい | GIDRルートからの相対ファイルパス。 |

**戻り値:** `{"status": 204, "path": "reports/july.csv"}`

**例外:** パスが空または無効な場合は `ValueError`。GCSからの削除に失敗した場合は `RuntimeError`。

```python theme={null}
def main():
    result = gidr_delete_gcs('reports/july.csv')
    return result
```

#### `gidr_list_gcs`

指定したパス配下のすべてのファイルを一覧表示します。デフォルトではGIDRルートフォルダ内のすべてのファイルを一覧表示します。

```python theme={null}
gidr_list_gcs(path='', max_results=1000)
```

| パラメータ         | 型     | 必須  | 説明                                              |
| ------------- | ----- | --- | ----------------------------------------------- |
| `path`        | `str` | いいえ | `reports/` など、一覧表示するサブフォルダ。デフォルトはGIDRルートです。     |
| `max_results` | `int` | いいえ | 返すファイルの最大数。デフォルトは `1000` で、結果は自動的にページネーションされます。 |

**戻り値:** GIDRルートからの相対ファイルパスのリスト。

```python theme={null}
# すべてのファイルを一覧表示
def main():
    return gidr_list_gcs()
```

```python theme={null}
# サブフォルダ内のファイルのみを一覧表示
def main():
    return gidr_list_gcs('reports/')
```

<Tip>
  `gidr_list_gcs` と `gidr_read_gcs` を組み合わせて、複数のファイルを処理できます。

  ```python theme={null}
  def main():
      files = gidr_list_gcs('reports/')
      results = {}
      for file_path in files:
          results[file_path] = gidr_read_gcs(file_path)
      return results
  ```
</Tip>

### データベース（DB）ユーティリティ関数

これらの組み込み関数を使用すると、GIDRのデータベースインスタンスにアクセスしてテーブルを作成できます。接続情報は実行時に注入されるため、データベース設定は不要です。

| 関数             | シグネチャ                                                 | 戻り値                          |
| -------------- | ----------------------------------------------------- | ---------------------------- |
| `gidr_get_db`  | `gidr_get_db() -> Generator[Session, None, None]`     | SQLAlchemy `Session` ジェネレータ。 |
| `create_table` | `create_table(table_name, columns, primary_key=None)` | `None`                       |

#### `gidr_get_db`

GIDRのデータベースインスタンスに接続されたSQLAlchemy `Session` を生成します。ジェネレータが使い尽くされると、セッションは自動的に閉じられます。

<Note>
  接続をプールへ戻すため、必ず `finally` ブロックで `db_gen.close()` を呼び出してください。`session.close()` を直接呼び出さず、ジェネレータにクリーンアップを任せてください。

  セッションは `autocommit=False` を使用するため、書き込み後は明示的に `session.commit()` を呼び出します。SQLAlchemyの `text()` はグローバルスコープにあらかじめインポートされているため、インポートは不要です。
</Note>

**例: 行を読み取る**

```python theme={null}
import datetime

def _json_safe(value):
    if value is None or isinstance(value, (str, int, float, bool)):
        return value
    if isinstance(value, (datetime.date, datetime.datetime)):
        return value.isoformat()
    if isinstance(value, bytes):
        return value.decode("utf-8", errors="replace")
    return str(value)

def main():
    db_gen = gidr_get_db()
    session = next(db_gen)
    try:
        rows = session.execute(
            text('SELECT * FROM "Sample_database_file" LIMIT 10')
        ).fetchall()
        return {
            "orders": [
                {key: _json_safe(value) for key, value in row._mapping.items()}
                for row in rows
            ]
        }
    finally:
        db_gen.close()
```

**例: 行を挿入する**

```python theme={null}
def main():
    product_name = global_variables.get("product_name")
    price = global_variables.get("price")
    db_gen = gidr_get_db()
    session = next(db_gen)
    try:
        session.execute(
            text("INSERT INTO products (name, price) VALUES (:name, :price)"),
            {"name": product_name, "price": price}
        )
        session.commit()
    finally:
        db_gen.close()
    return {"status": "inserted"}
```

#### `create_table`

GIDRのデータベースインスタンスにテーブルを作成し、SQL Agentへ登録します。これにより、後続のワークフローステップでテーブルをクエリできます。

すべてのテーブルには、`row_id BIGINT` のID列が自動生成されます。定義する必要はありません。

```python theme={null}
create_table(table_name, columns, primary_key=None)
```

| パラメータ         | 型                | 必須  | 説明                                |
| ------------- | ---------------- | --- | --------------------------------- |
| `table_name`  | `str`            | はい  | 新しいテーブルの名前。                       |
| `columns`     | `dict[str, str]` | はい  | `{column_name: sql_type}` のマッピング。 |
| `primary_key` | `str`            | いいえ | 主キーとして指定する列の名前。                   |

**サポートされるSQL型**

| 型            | 用途                  |
| ------------ | ------------------- |
| `TEXT`       | 文字列および自由形式のテキスト。    |
| `VARCHAR(n)` | 最大長を指定したテキスト。       |
| `INTEGER`    | 整数。                 |
| `BIGINT`     | 大きな整数。              |
| `FLOAT`      | 小数。                 |
| `BOOLEAN`    | 真偽値。                |
| `DATE`       | `YYYY-MM-DD` 形式の日付。 |
| `TIMESTAMP`  | 日付と時刻の値。            |
| `JSONB`      | JSONオブジェクト。         |

**例: 基本的なテーブル**

```python theme={null}
def main():
    create_table(
        "customers",
        {
            "name": "TEXT",
            "email": "VARCHAR(255)",
            "age": "INTEGER"
        }
    )
    return {"status": "table created"}
```

**例: 主キーを持つテーブル**

```python theme={null}
def main():
    create_table(
        "products",
        {
            "product_code": "VARCHAR(50)",
            "product_name": "TEXT",
            "price": "FLOAT",
            "in_stock": "BOOLEAN"
        },
        primary_key="product_code"
    )
    return {"status": "ok"}
```

<AccordionGroup>
  <Accordion title="内部で行われる処理">
    `create_table` は、`gidr_get_db` が返すセッションを使用してテーブルを作成し、DDLをコミットしてスキーマをJSONとしてシリアライズし、`ai_services.public.sql_agent_user_tables_map` にレコードを挿入します。これにより、SQL Agentは後続のワークフローステップで新しいテーブルを検出してクエリできます。
  </Accordion>

  <Accordion title="制限事項">
    * 既に存在する名前でテーブルを作成するとエラーになります。一意の名前を使用するか、先に既存のテーブルを削除してください。
    * 列の型には、`string` ではなく `TEXT` のような有効なSQL型文字列を指定する必要があります。
    * `primary_key` を指定する場合、その列は `columns` にも含まれている必要があります。
    * 新しいテーブルは0行の状態で作成されます。
  </Accordion>
</AccordionGroup>

### セキュリティ制限

プラットフォームの安定性を確保するために、以下は **ブロック** されています：

* **ファイルシステム**: ファイルI/O操作なし（例：`open()`）。
* **システムアクセス**: 許可リスト外のOS/システム関数または任意のインポートなし。

<Warning>
  コード実行にはリソース制限とタイムアウトがあります。無限ループやメモリ集約的な操作は避けてください。
</Warning>
