データをアップロードしたら、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 を返します。limit と offset パラメータでどのページを取得するか制御します。
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)
Time series
Properties
File
時系列データ、ステップ統計、サイクルメトリクスを返します: フィールド 説明 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())
プロパティを含む測定メタデータを返します。ファイルデータは取得されません。 detail = client.cell_measurement.detail(measurement_id)
props = detail.measurement.properties
print ( f "Thickness: { props[ 'thickness' ][ 'value' ] } { props[ 'thickness' ][ 'unit' ] } " )
添付されたすべてのファイルをダウンロードし、ファイル名をバイト列にマップする files 辞書として返します: detail = client.cell_measurement.detail(measurement_id)
for filename, content in detail.files.items():
with open (filename, "wb" ) as f:
f.write(content)
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: キャッシュ付きの階層走査
Navigator は、spec → instance → measurement の階層を走査し、すべての list / fetch 呼び出しをメモリ上にメモ化するオプトインのヘルパーです。1 つのスクリプトやノートブック内で複数の spec、instance、measurement を反復処理し、同じ API 呼び出しの繰り返しを避けたいときに使います。
Navigator を使うべきケース:
1 つ以上のセル仕様上のすべての測定をループする解析スクリプトを書いている。
反復順序を決定論的にしたい — 一覧は name でソートされて返されます。
limit と offset を自分で管理せずに、ページングを自動で処理させたい。
基礎となるサブクライアント (client.cell_spec、client.cell_instance、client.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 往復なしで同じリストが返されます。measurements、steps、time_series も同様です。
nav = Navigator( client = Ionworks(), page_size = 200 )
パラメータ 説明 client既存の Ionworks クライアント。省略した場合はデフォルトのクライアントが作成されます (IONWORKS_API_KEY を環境変数から読み込みます)。 page_sizecell_instance.list と cell_measurement.list のページング時の 1 ページあたりのアイテム数。デフォルトは 200。
単一の spec を参照する
名前が一致しない場合、利用可能な 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_measurement の steps、cycles、steps_and_cycles、time_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_FOUND、CONFLICT、BAD_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 ドキュメント を参照してください。
次のステップ
データの可視化 ブラウザ内のインタラクティブビューアでアップロードしたデータを探索します。
データのアップロード 仕様、インスタンス、測定のエンドツーエンドアップロードワークフロー。
シミュレーション API Python API でシミュレーションとパイプラインを実行します。