メインコンテンツへスキップ
データをアップロードしたら、ionworks-api Python クライアントで読み戻せます。このページではリソースの一覧とフィルタリング、完全な測定詳細の取得、ローカルキャッシング、Python 内でのプロット、エラー処理について説明します。 インストールと認証についてはPython API クライアントページを参照してください。アップロードについてはデータのアップロードを参照してください。
どのセル仕様、インスタンス、測定の ID も、Ionworks Studio のデータ可視化ページから確認できます。ID は URL と詳細パネルに表示されます。

リソースの一覧

# List cell specifications (first page)
specs = client.cell_spec.list()
for spec in specs[:5]:
    print(f"  - {spec.name} (form_factor: {spec.form_factor})")

# Get a specific cell spec with full nested data
full_spec = client.cell_spec.get(spec_id)
print(f"Capacity: {full_spec.ratings['capacity']['value']} "
      f"{full_spec.ratings['capacity']['unit']}")

# List instances for a spec and pick the first
instances = client.cell_instance.list(spec_id)
instance = instances[0]

# List measurements for an instance
measurements = client.cell_measurement.list(instance.id)

フィルタリングと並び替え

すべての list() メソッドはキーワード専用のフィルタパラメータを受け入れるため、すべてを取得してから Python でフィルタリングする代わりに、サーバー側で結果を絞り込めます。
# Search cell specs by name (case-insensitive substring match)
specs = client.cell_spec.list(name="graphite")

# Exact name match
specs = client.cell_spec.list(name_exact="NCM622/Graphite Coin Cell")

# Filter by form factor (cell specs only)
specs = client.cell_spec.list(form_factor="R2032")

# Filter by creator
specs = client.cell_spec.list(created_by_email="jane")

# Date range filters
specs = client.cell_spec.list(
    created_after="2026-01-01T00:00:00Z",
    created_before="2026-04-01T00:00:00Z",
)

# Sort results
specs = client.cell_spec.list(order_by="created_at", order="desc")
フィルタは 3 つのリソースタイプすべてで同じように動作し、1 回の呼び出しでページングや並び替えと組み合わせられます:
instances = client.cell_instance.list(
    spec_id,
    limit=50,
    offset=0,
    name="batch-A",
    order_by="updated_at",
    order="desc",
)

measurements = client.cell_measurement.list(
    instance_id,
    measurement_type="time_series",
    created_after="2026-03-01T00:00:00Z",
    order_by="created_at",
    order="asc",
)
セル測定では測定開始時刻に対する追加の日付フィルタがサポートされます:
measurements = client.cell_measurement.list(
    instance_id,
    started_after="2026-03-01T00:00:00Z",
    started_before="2026-03-31T23:59:59Z",
)

フィルタパラメータ

パラメータ説明利用可能対象
namestr名前への大文字小文字を区別しない部分一致。すべて
name_exactstr名前の完全一致。name より優先される。すべて
form_factorstrフォームファクターの完全一致。cell_spec のみ
measurement_typestr測定タイプ("time_series""properties""file")でフィルタ。cell_measurement のみ
created_by_emailstr作成者メールへの大文字小文字を区別しない部分一致。すべて
created_afterstrISO datetime、この時刻以降に作成されたレコード。すべて
created_beforestrISO datetime、この時刻以前に作成されたレコード。すべて
updated_afterstrISO datetime、この時刻以降に更新されたレコード。すべて
updated_beforestrISO datetime、この時刻以前に更新されたレコード。すべて
started_afterstrISO datetime、この時刻以降に開始された測定。cell_measurement のみ
started_beforestrISO datetime、この時刻以前に開始された測定。cell_measurement のみ
order_bystrソートする列("name""created_at""updated_at"、測定では "start_time")。すべて
orderstrソート方向: "asc" または "desc"すべて
フィルタパラメータは互いに自由に組み合わせられ、limit/offset ページングパラメータとも組み合わせられます。返される PaginatedList.total プロパティは、フィルタ適用後の総数を反映します。

ページング

すべての list() 呼び出しは PaginatedList を返します。limitoffset パラメータでどのページを取得するか制御します。
page = client.cell_spec.list(limit=50, offset=0)
print(f"Showing {page.count} of {page.total} specs")

next_page = client.cell_spec.list(limit=50, offset=50)
パラメータデフォルト説明
limitintサーバーデフォルト (1000)返すアイテムの最大数(1 から 1000)。
offsetint0結果を返す前にスキップするアイテム数。
返される PaginatedList は通常の Python リストのように動作(反復、インデックス、長さチェック)し、さらに次のプロパティを公開します:
プロパティ説明
.items現在のページの結果リスト。
.totalすべてのページにわたるマッチするレコードの総数。
.count現在のページのアイテム数。
すべての結果を反復するには:
all_specs = []
offset = 0
limit = 100
while True:
    page = client.cell_spec.list(limit=limit, offset=offset)
    all_specs.extend(page.items)
    if len(all_specs) >= page.total:
        break
    offset += limit

測定詳細

client.cell_measurement.detail() は完全な測定を取得し、測定タイプに基づいてレスポンスを適応させます。
measurement_detail = client.cell_measurement.detail(measurement_id)
時系列データ、ステップ統計、サイクルメトリクスを返します:
フィールド説明
measurement測定メタデータ(名前、プロトコル、テストセットアップ、メモ)
time_seriesDataFrame としての完全な時系列データ(デフォルトは polars)
stepsステップレベル統計 DataFrame
cyclesサイクルレベルメトリクス(容量、効率など) DataFrame
specification_id親セル仕様の ID(client.cell_spec.get(id) で取得)
instance_id親セルインスタンスの ID(client.cell_instance.get(spec_id, id) で取得)
detail = client.cell_measurement.detail(measurement_id)
print(f"Time series shape: {detail.time_series.shape}")
print(detail.cycles.head())

Web アプリへのリンク

client.urls.measurement() を使用して、Ionworks Web アプリの測定詳細ページへのリンクを作成します。ノートブック、スクリプト、レポートからクリック可能なリンクを表示して、共同作業者が Ionworks Studio の測定に直接ジャンプできるようにする場合に便利です。
url = client.urls.measurement(measurement_id, project_id)
# https://app.ionworks.com/dashboard/projects/<project_id>/data/measurements/<measurement_id>
パラメータ説明
measurement_idstrリンク先の測定の ID。
project_idstr測定が属するプロジェクトの ID。
ヘルパーは完全にローカルで実行され(ネットワーク呼び出しなし)、クライアントが使用するように設定されている API ホストに関係なく、常に https://app.ionworks.com 上の URL を返します。 一般的なパターンは、測定を反復しながら各結果の隣にリンクをレンダリングすることです:
for m in client.cell_measurement.list(instance_id):
    print(f"{m.name}: {client.urls.measurement(m.id, project_id)}")
Navigator は、spec → instance → measurement の階層を走査し、すべての list / fetch 呼び出しをメモリ上にメモ化するオプトインのヘルパーです。1 つのスクリプトやノートブック内で複数の spec、instance、measurement を反復処理し、同じ API 呼び出しの繰り返しを避けたいときに使います。 Navigator を使うべきケース:
  • 1 つ以上のセル仕様上のすべての測定をループする解析スクリプトを書いている。
  • 反復順序を決定論的にしたい — 一覧は name でソートされて返されます。
  • limitoffset を自分で管理せずに、ページングを自動で処理させたい。
基礎となるサブクライアント (client.cell_specclient.cell_instanceclient.cell_measurement) は引き続きメインの API です。Navigator はその上に乗る薄いレイヤーで、階層をキャッシュ済みの一貫したビューとして扱いたいときに使い、単発の読み取りや書き込みではサブクライアントを直接使ってください。
from ionworks import Ionworks, Navigator

nav = Navigator(Ionworks())

# すべての spec、instance、measurement を巡回する
for spec_name in nav.specs():
    for inst in nav.instances(spec_name):
        for m in nav.measurements(inst.id):
            ts = nav.time_series(m.id)
            steps = nav.steps(m.id)
            # ... 解析処理 ...
各エンティティは Navigator インスタンスごとに最大 1 回しか取得されません。nav.instances("CellA") を 2 回呼び出しても、2 回目の API 往復なしで同じリストが返されます。measurementsstepstime_series も同様です。

設定

nav = Navigator(client=Ionworks(), page_size=200)
パラメータ説明
client既存の Ionworks クライアント。省略した場合はデフォルトのクライアントが作成されます (IONWORKS_API_KEY を環境変数から読み込みます)。
page_sizecell_instance.listcell_measurement.list のページング時の 1 ページあたりのアイテム数。デフォルトは 200

単一の spec を参照する

spec = nav.spec("CellA")
名前が一致しない場合、利用可能な spec 名のリストとともに KeyError を送出します — タイポの検出に便利です。

キャッシュの無効化

電池データはアップロード後は不変なので、唯一の陳腐化要因は「プラットフォームに新しい兄弟エンティティが現れた」場合だけです。セッションの途中で新しいデータがアップロードされる可能性がある長時間動作のノートブックでは、キャッシュの一部または全体を破棄できます:
nav.clear()                                   # すべてを破棄
nav.invalidate(spec_name="CellA")             # CellA と、その instance および measurement を破棄
nav.invalidate(instance_id="inst_123")        # 1 つの instance と、その measurement を破棄
nav.invalidate(measurement_id="meas_456")     # 1 つの measurement の steps と time series を破棄
無効化は下方向にカスケードします: spec を破棄するとその instance と measurement も破棄され、instance を破棄するとその measurement も破棄されます。
Navigator はインスタンスの生存期間中、メモリ上にキャッシュします。プロセスをまたいだ、あるいはセッションをまたいだ測定データのディスクキャッシュについては、下記の ローカルキャッシング を参照してください — 両レイヤーは組み合わせて利用できます。

ローカルキャッシング

ionworks-api クライアントは測定データをディスクに自動的にキャッシュし、繰り返しの読み取りを高速化し不要な API 呼び出しを回避します。キャッシングはデフォルトで有効で、cell_measurementstepscyclessteps_and_cyclestime_series メソッドに適用されます。 client.cell_measurement.steps(measurement_id) のようなメソッドを呼び出すと、クライアントは API リクエストを行う前にローカルキャッシュディレクトリを確認します。キャッシュされたコピーが存在し有効期限内であれば、それを直接返します。それ以外の場合、クライアントは API から取得し、結果をキャッシュして返します。 キャッシュされたデータはデフォルトで ~/.ionworksdata_cache に Parquet ファイルとして保存され、1 時間で有効期限が切れます。

キャッシュをスキップする

すべてのデータ取得メソッドは use_cache パラメータを受け入れます。False に設定すると、ローカルキャッシュからの読み取りも書き込みも行わずに新しい API 呼び出しを強制します:
steps = client.cell_measurement.steps(measurement_id, use_cache=False)
time_series = client.cell_measurement.time_series(measurement_id, use_cache=False)

キャッシュの設定

import ionworks

ionworks.set_cache_directory("/path/to/custom/cache")
ionworks.set_cache_ttl(7200)              # 2 hours
ionworks.set_cache_ttl(None)              # never expire
ionworks.set_cache_enabled(False)
ionworks.set_cache_enabled(True)
deleted_count = ionworks.clear_cache()
関数説明
set_cache_enabled(bool)キャッシングをグローバルに有効化・無効化します。
get_cache_enabled()キャッシングが現在有効かどうかを返します。
set_cache_directory(path)キャッシュファイルのディレクトリを設定します。デフォルト: ~/.ionworksdata_cache
set_cache_ttl(seconds)TTL を秒単位で設定します。None で有効期限を無効化。デフォルト: 3600
get_cache_directory()現在のキャッシュディレクトリパスを返します。
get_cache_ttl()現在の TTL 値を返します。
clear_cache()キャッシュされたすべてのファイルを削除し、削除した数を返します。
キャッシュ設定はグローバルです。変更は同じ Python プロセス内のその後のすべての API 呼び出しに影響します。

Python からのプロット

DataLoader には、測定データを matplotlib ベースで素早く可視化する plot_data() メソッドが含まれています。プロットは電圧と電流の時間変化を表示し、温度データが利用可能な場合は追加の温度サブプロットを表示します。
from ionworksdata import DataLoader

loader = DataLoader.from_db("measurement-id-here")
fig, ax = loader.plot_data()
メソッドは matplotlib の (Figure, Axes) タプルを返すため、プロットをさらにカスタマイズできます。プロットを即座に表示するには show=True を渡します:
fig, ax = loader.plot_data(show=True)
plot_data() は時系列データがまだ取得されていない場合、サーバーから自動的に読み込みます。
ブラウザ内のインタラクティブなビューア(フィルタ、ステップオーバーレイ、SQL 付き)についてはデータの可視化を参照してください。

インライン時系列のサイズ制限

API 呼び出しに pandas または polars DataFrame を直接渡す場合(例: パイプライン設定の一部として)、クライアントはインライン時系列データに対して最大 1,000 行 を強制します。より大きなデータセットは最初に測定としてアップロードし、ID で参照する必要があります。
from ionworks import MeasurementValidationError, IonworksError

try:
    client.pipeline.run(config_with_large_inline_df)
except MeasurementValidationError as e:
    # Specifically handle the size limit violation
    print(e)
    # "Time series has 5000 rows, which exceeds the maximum of 1000 rows
    #  for inline data. Upload the data as a measurement using
    #  client.cell_measurement.create() and reference it with
    #  'db:<measurement_id>' or iwdata.DataLoader.from_db(MEASUREMENT_ID)
    #  instead."
except IonworksError as e:
    print(e)
大きなデータセットを扱うには、まずアップロードして ID で参照します:
bundle = client.cell_measurement.create(instance_id, measurement_data)

from ionworksdata import DataLoader
loader = DataLoader.from_db(bundle.measurement.id)

DataLoader 設定のエクスポート

データベース測定を参照する DataLoader があり、自己完結型の設定をエクスポートしたい場合(例: 同僚と共有するため)、to_local() でデータをインライン化します:
from ionworksdata import DataLoader

loader = DataLoader.from_db("measurement-id-here")
local_loader = loader.to_local()

# Now to_config() returns the full data instead of a DB reference
config = local_loader.to_config()
to_local() はすべての時系列とステップデータをサーバーから即座に取得します。非常に大きな測定では時間がかかることがあります。

エラー処理

クライアントは一般的なエラーケースに対して例外を発生させます:
  • API 資格情報が欠落・無効
  • API リクエストエラー(詳細付きで IonworksError を発生)
  • 1,000 行を超えるインライン時系列(IonworksError のサブクラス MeasurementValidationError を発生)
from ionworks import IonworksError

try:
    client.cell_spec.list()
except IonworksError as e:
    print(f"API error: {e}")
MeasurementValidationError の処理パターンは上記のインライン時系列のサイズ制限を参照してください。

API エラー形式

すべての API エラーは一貫した JSON 構造を返します:
{
  "error_code": "CONFLICT",
  "message": "Cell specification with this name already exists",
  "detail": {
    "resource_type": "cell_specification",
    "resource_name": "My Cell Spec",
    "existing_id": "abc-123"
  }
}
フィールド説明
error_codestring機械可読のエラーコード(例: NOT_FOUNDCONFLICTBAD_REQUEST)。
messagestring何が間違っているかの人間可読の説明。
detailobject | nullエラーに関する追加コンテキスト(任意)。エラータイプによって異なり、エラーによっては存在しないことがあります。
一般的な HTTP ステータスコード:
ステータスエラーコード説明
400BAD_REQUESTリクエストが無効、または必須フィールドが欠落しています。
403FORBIDDENこのリソースにアクセスする権限がありません。API 資格情報が欠落または無効な場合にも返されます(API は 401 を使用しません)。
404NOT_FOUNDリクエストされたリソースが存在しません。
409CONFLICT同じ名前または識別子のリソースがすでに存在します。detail フィールドに existing_id が含まれることがあります。
429USAGE_LIMIT_REACHEDこの請求サイクルで組織の使用量クォータを超えました。

完全な API リファレンス

完全な Python API リファレンスはionworks-api ドキュメントを参照してください。

次のステップ

データの可視化

ブラウザ内のインタラクティブビューアでアップロードしたデータを探索します。

データのアップロード

仕様、インスタンス、測定のエンドツーエンドアップロードワークフロー。

測定

3 つの測定タイプの詳細。

シミュレーション API

Python API でシミュレーションとパイプラインを実行します。