0 フォロワー · 102 投稿

Pythonは、汎用プログラミング用のインタープリター型の高水準のプログラム言語です。 Guido van Rossumによって作成され、1991年に最初にリリースされたPythonは、特に重要な空白を使用してコードの可読性を強調する設計哲学を持っています。 公式サイト。

InterSystems Python Binding Documentatión.

記事 Toshihiko Minamoto · 11月 5, 2025 8m read

新しい InterSystems IRIS® Cloud SQL と InterSystems IRIS® Cloud IntegratedML® クラウド製品のユーザーであり、デプロイメントのメトリクスにアクセスして独自の可観測性プラットフォームに送信しようと考えている方のために、メトリクスを Google Cloud Platform Monitoring(旧称 StackDriver)に送信して手っ取り早く行う方法をご紹介します。

クラウドポータルには、概要メトリクス表示用のトップレベルのメトリクスが含まれており、ユーザーに公開されているメトリクスエンドポイントを使用しますが、ある程度探索しなければ、そこにあることには気づきません。

🚩 このアプローチは、「今後名前が付けられる予定の機能」を利用している可能性があるため、それを踏まえると将来性があるものではなく、確実に InterSystemsでサポートされているアプローチではありません。


では、より包括的なセットをエクスポートしたい場合はどうでしょうか?この技術的な記事/例では、メトリクスを取得して可観測性に転送する方法を紹介します。Open Telemetry Collector を使用して、任意のメトリクスターゲットを取得し、任意の可観測性プラットフォーム送信できるように、ニーズに合わせて変更することができます。

上記の結果に導く仕組みは多数の方法で得られますが、ここでは Kubernetes pod を使用して、1 つのコンテナーで Python スクリプトを実行し、もう 1 つのコンテナーで Otel を実行して、メトリクスのプルとプッシュを行います... 自分のやり方を選択することはできますが、この例と記事では、k8s を主人公に Python を使って行います。

手順:

  • 前提条件
  • Python
  • コンテナー
  • Kubernetes
  • Google Cloud Monitoring

前提要件:

  • IRIS®  Cloud SQL の有効なサブスクリプション
  • 実行中の 1 つのデプロイメント(オプションで Integrated ML を使用)
  • 環境に提供するシークレット

環境変数

 
 シークレットの取得
この内容は少し複雑で本題から少し外れているためティーザーに入れましたが、これがシークレットの生成に必要なる値です。
ENV IRIS_CLOUDSQL_USER 'user'
ENV IRIS_CLOUDSQL_PASS 'pass'

☝ これは https://portal.live.isccloud.io の認証情報です。

ENV IRIS_CLOUDSQL_USERPOOLID 'userpoolid'
ENV IRIS_CLOUDSQL_CLIENTID 'clientid'
ENV IRIS_CLOUDSQL_API 'api'

☝ これはブラウザの開発ツールから取得する必要があります。

  • `aud` = clientid
  • `userpoolid`= iss
  • `api` = request utl

ENV IRIS_CLOUDSQL_DEPLOYMENTID 'deploymentid'

☝これはクラウドサービスポータルから取得できます

 

Python:

以下に、クラウドポータルからメトリクスを取得し、それを Otel Collectorが取得するメトリクスとしてローカルにエクスポートする Python ハッキングを示します。

 
iris_cloudsql_exporter.py
import time
import os
import requests
import json

from warrant import Cognito from prometheus_client.core import GaugeMetricFamily, REGISTRY, CounterMetricFamily from prometheus_client import start_http_server from prometheus_client.parser import text_string_to_metric_families

classIRISCloudSQLExporter(object):definit(self): self.access_token = self.get_access_token() self.portal_api = os.environ['IRIS_CLOUDSQL_API'] self.portal_deploymentid = os.environ['IRIS_CLOUDSQL_DEPLOYMENTID']

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">collect</span><span class="hljs-params">(self)</span>:</span>
    <span class="hljs-comment"># Requests fodder</span>
    url = self.portal_api
    deploymentid = self.portal_deploymentid
    print(url)
    print(deploymentid)

    headers = {
        <span class="hljs-string">'Authorization'</span>: self.access_token, <span class="hljs-comment"># needs to be refresh_token, eventually</span>
        <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
    }

    metrics_response = requests.request(<span class="hljs-string">"GET"</span>, url + <span class="hljs-string">'/metrics/'</span> + deploymentid, headers=headers)
    metrics = metrics_response.content.decode(<span class="hljs-string">"utf-8"</span>)

    <span class="hljs-keyword">for</span> iris_metrics <span class="hljs-keyword">in</span> text_string_to_metric_families(metrics):
        <span class="hljs-keyword">for</span> sample <span class="hljs-keyword">in</span> iris_metrics.samples:

            labels_string = <span class="hljs-string">"{1}"</span>.format(*sample).replace(<span class="hljs-string">'\''</span>,<span class="hljs-string">"\""</span>)
            labels_dict = json.loads(labels_string)
            labels = []

            <span class="hljs-keyword">for</span> d <span class="hljs-keyword">in</span> labels_dict:
                labels.extend(labels_dict)
            <span class="hljs-keyword">if</span> len(labels) &gt; <span class="hljs-number">0</span>:
                g = GaugeMetricFamily(<span class="hljs-string">"{0}"</span>.format(*sample), <span class="hljs-string">'Help text'</span>, labels=labels)
                g.add_metric(list(labels_dict.values()), <span class="hljs-string">"{2}"</span>.format(*sample))
            <span class="hljs-keyword">else</span>:
                g = GaugeMetricFamily(<span class="hljs-string">"{0}"</span>.format(*sample), <span class="hljs-string">'Help text'</span>, labels=labels)
                g.add_metric([<span class="hljs-string">""</span>], <span class="hljs-string">"{2}"</span>.format(*sample))
            <span class="hljs-keyword">yield</span> g

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_access_token</span><span class="hljs-params">(self)</span>:</span>
    <span class="hljs-keyword">try</span>:
        user_pool_id = os.environ[<span class="hljs-string">'IRIS_CLOUDSQL_USERPOOLID'</span>] <span class="hljs-comment"># isc iss </span>
        username = os.environ[<span class="hljs-string">'IRIS_CLOUDSQL_USER'</span>]
        password = os.environ[<span class="hljs-string">'IRIS_CLOUDSQL_PASS'</span>]
        clientid = os.environ[<span class="hljs-string">'IRIS_CLOUDSQL_CLIENTID'</span>] <span class="hljs-comment"># isc aud </span>
        print(user_pool_id)
        print(username)
        print(password)
        print(clientid)
        
        <span class="hljs-keyword">try</span>:
            u = Cognito(
                user_pool_id=user_pool_id,
                client_id=clientid,
                user_pool_region=<span class="hljs-string">"us-east-2"</span>, <span class="hljs-comment"># needed by warrant, should be derived from poolid doh</span>
                username=username
            )
            u.authenticate(password=password)
        <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> p:
            print(p)
    <span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
        print(e)

    <span class="hljs-keyword">return</span> u.id_token

ifname == 'main':

start_http_server(<span class="hljs-number">8000</span>)
REGISTRY.register(IRISCloudSQLExporter())
<span class="hljs-keyword">while</span> <span class="hljs-keyword">True</span>:
    REGISTRY.collect()
    print(<span class="hljs-string">"Polling IRIS CloudSQL API for metrics data...."</span>)
    <span class="hljs-comment">#looped e loop</span>
    time.sleep(<span class="hljs-number">120</span>)</code></pre>

 

Docker:

 
Dockerfile
FROM python:3.8ADD src /src
RUN pip install prometheus_client
RUN pip install requests
WORKDIR /src
ENV PYTHONPATH '/src/'ENV PYTHONUNBUFFERED=1ENV IRIS_CLOUDSQL_USERPOOLID 'userpoolid'ENV IRIS_CLOUDSQL_CLIENTID 'clientid'ENV IRIS_CLOUDSQL_USER 'user'ENV IRIS_CLOUDSQL_PASS 'pass'ENV IRIS_CLOUDSQL_API 'api'ENV IRIS_CLOUDSQL_DEPLOYMENTID 'deploymentid'RUN pip install -r requirements.txt
CMD ["python" , "/src/iris_cloudsql_exporter.py"]
docker build -t iris-cloudsql-exporter .
docker image tag iris-cloudsql-exporter sween/iris-cloudsql-exporter:latest
docker push sween/iris-cloudsql-exporter:latest


デプロイメント:

k8s、ネームスペースを作成します:

kubectl create ns iris

k8s、シークレットを追加します:

kubectl create secret generic iris-cloudsql -n iris \
    --from-literal=user=$IRIS_CLOUDSQL_USER \
    --from-literal=pass=$IRIS_CLOUDSQL_PASS \
    --from-literal=clientid=$IRIS_CLOUDSQL_CLIENTID \
    --from-literal=api=$IRIS_CLOUDSQL_API \
    --from-literal=deploymentid=$IRIS_CLOUDSQL_DEPLOYMENTID \
    --from-literal=userpoolid=$IRIS_CLOUDSQL_USERPOOLID

otel、構成を作成します:

apiVersion: v1
data:
  config.yaml: |
    receivers:
      prometheus:
        config:
          scrape_configs:
          - job_name: 'IRIS CloudSQL'
              # Override the global default and scrape targets from this job every 5 seconds.
            scrape_interval: 30s
            scrape_timeout: 30s
            static_configs:
                    - targets: ['192.168.1.96:5000']
            metrics_path: /
exporters:
  googlemanagedprometheus:
    project: "pidtoo-fhir"
service:
  pipelines:
    metrics:
      receivers: [prometheus]
      exporters: [googlemanagedprometheus]

kind: ConfigMap metadata: name: otel-config namespace: iris

k8s、otel 構成を configmap としてロードします:

kubectl -n iris create configmap otel-config --from-file config.yaml

k8s、ロードバランサー(確実にオプション)、MetalLB をデプロイします。これはクラスタ外部からグスクレイピングして検査するために行っています。

cat <<EOF | kubectl apply -f -n iris -
apiVersion: v1
kind: Service
metadata:
  name: iris-cloudsql-exporter-service
spec:
  selector:
    app: iris-cloudsql-exporter
  type: LoadBalancer
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 8000
EOF

gcp、Google Cloud へのキーが必要です。サービスアカウントにスコープを設定する必要があります

  • roles/monitoring.metricWriter
kubectl -n iris create secret generic gmp-test-sa --from-file=key.json=key.json

k8s; deployment/pod そのもの。2 つのコンテナー:

 
deployment.yaml
kubectl -n iris apply -f deployment.yaml

実行

特に問題がなければ、ネームスペースを詳しく調べて、状況を確認してみましょう。

✔ GCP と Otel 用の 2 つの configmap

 

✔ 1 つのロードバランサー

 

✔ 1 つの pod、2 つのコンテナーが正しくスクレイピングされます

  

Google Cloud Monitoring

可観測性を調べてメトリクスが正しく受信されていることを確認し、可観測性を高めましょう!

 

0
0 20
記事 Toshihiko Minamoto · 10月 30, 2025 7m read

img

この記事では、IRIS環境におけるPythonプログラミングの基礎について紹介します。

本題に入る前に、重要なトピックである「Pythonの仕組み」について説明します。これは、IRIS環境でPythonを使用して作業する際に起こりうる問題や制限を理解するのに役立ちます。

すべての記事と例は、以下のgitリポジトリで確認できます: iris-python-article

Pythonの仕組み

インタープリター型言語

Pythonはインタープリター型言語であり、コードはランタイム時に1行ずつ実行されます。スクリプトをインポートする場合でも同様です。

これはどういうことでしょうか? 以下のコードを見てみましょう。

# introduction.py

def my_function():
    print("Hello, World!")

my_function()

このスクリプトを実行すると、Pythonインタープリターはコードを1行ずつ読み取ります。 まず最初に関数 my_function を定義してから、その関数を呼び出すと、コンソールに「Hello, World!」と出力されます。

スクリプトを直接実行している例:

python3 /irisdev/app/src/python/article/introduction.py 

出力は以下のようになります。

Hello, World!

IRIS環境でこのスクリプトをインポートするとどうなるのでしょうか?

Class Article.Introduction Extends %RegisteredObject
{
    ClassMethod Run()
    {
        Set sys = ##class(%SYS.Python).Import("sys")
        do sys.path.append("/irisdev/app/src/python/article")

        do ##class(%SYS.Python).Import("introduction")
    }
}

実行しましょう。

iris session iris -U IRISAPP '##class(Article.Introduction).Run()'

出力が表示されます。

Hello, World!

これは、Pythonインタープリターがコードを解釈しながらインポートするためで、最初に関数を定義し、その後に関数を呼び出します。これはスクリプトを直接実行した場合と同じ動作ですが、実行しているのではなくインポートしています

⚠️ 重要な注意事項:関数を呼び出さずにスクリプトをインポートしても、何も起こりません。 関数は定義されますが、明示的に呼び出さない限り実行されません。

分かりましたか? Pythonインタープリターはファイル内のコードを実行しますが、関数を呼び出さなければ、その関数は実行されません。

呼び出さずにインポートする例:

# introduction1.py
def my_function():
    print("Hello, World!")

Pythonインタープリターで実行しましょう。

python3 /irisdev/app/src/python/article/introduction1.py 

出力:

# 関数は定義されていますが、呼び出されていないため、出力はありません

IRIS環境にこのスクリプトをインポートすると:

Class Article.Introduction1 Extends %RegisteredObject
{
    ClassMethod Run()
    {
        Set sys = ##class(%SYS.Python).Import("sys")
        do sys.path.append("/irisdev/app/src/python/article")
        do ##class(%SYS.Python).Import("introduction1")
    }
}

実行しましょう。

iris session iris -U IRISAPP '##class(Article.Introduction1).Run()'

関数は定義されていますが、呼び出されていないため、出力はありません。

🤯この微妙な違いが重要な理由

  • Pythonスクリプトをインポートすると、そのスクリプトのコードが実行されます。
    • コードを実行したくない場合があります
  • インポートするとスクリプトが実行されているように見えるかもしれませんが、実際には直接実行されているわけではないため、混乱を招く可能性があります。

インポートのキャッシュ

Pythonスクリプトをインポートすると、Pythonインタープリターがインポートされたスクリプトをキャッシュします。 つまり、同じスクリプトをもう一度インポートすると、そのスクリプトのコードは再実行されず、キャッシュされたバージョンが使用されます。

具体例による説明:

introduction.py スクリプトを再利用しましょう。

# introduction.py
def my_function():
    print("Hello, World!")

my_function()

次に、同じように Article.Introduction クラスを再利用しましょう。

Class Article.Introduction Extends %RegisteredObject
{
    ClassMethod Run()
    {
        Set sys = ##class(%SYS.Python).Import("sys")
        do sys.path.append("/irisdev/app/src/python/article")
        do ##class(%SYS.Python).Import("introduction")
    }
}

今度は、同じIRISセッション内で2回続けて実行します。

iris session iris -U IRISAPP 

IRISAPP>do ##class(Article.Introduction).Run()
Hello, World!

IRISAPP>do ##class(Article.Introduction).Run()

IRISAPP>

🤯一体どういうことでしょうか?

はい、「Hello, World!」は一度だけ出力されます!

⚠️ インポートされたスクリプトはキャッシュされています。 つまり、インポートした後にスクリプトを変更しても、IRSセッションが変更されるまで変更は反映されません。

IRISで language tag を使用する場合でも同じです。

Class Article.Introduction2 Extends %RegisteredObject
{

ClassMethod Run() [ Language = python ]
{
    import os

    if not hasattr(os, 'foo'):
        os.foo = "bar"
    else:
        print("os.foo already exists:", os.foo)
}

}

実行しましょう。

iris session iris -U IRISAPP

IRISAPP>do ##class(Article.Introduction2).Run()

IRISAPP>do ##class(Article.Introduction2).Run()
os.foo already exists: bar

なんと、os モジュールはキャッシュされ、foo 属性は存在しないことに再定義されていません。

まとめ

この入門編が、IRISでPythonを使用する際に、特にスクリプトのインポートやキャッシュ処理に関して、予期しない動作が発生する理由を理解する助けになれば幸いです。

IRISでPythonを使う際のポイント:

  • Pythonスクリプトで変更を確認するには、IRISセッションを毎回変更する。
    • これはバグではなく、Pythonの仕様です。
  • スクリプトをインポートするとそのコードが実行されることに気を付ける。

ボーナス

待って! スクリプトをインポートするとキャッシュされる?つじつまが合いません。 language tag = python で作業していて、スクリプトを変更したのにIRISセッションを変更しなくてもうまく動作するのは何故でしょうか?

いい質問です。これは language tag の仕組みが関係しています。language tag は実行するたびにスクリプトをもう一度読み込み、ネイティブのPythonインタープリターで新しい行を入力するかのように、行ごとに実行します。language tag はスクリプトをインポートするわけではなく、Pythonインタープリターを再起動せずに直接スクリプトを実行しているのと同じ動作をします。

例:

Class Article.Introduction2 Extends %RegisteredObject
{
ClassMethod Run() [ Language = python ]
{
    import os

    if not hasattr(os, 'foo'):
        os.foo = "bar"
    else:
        print("os.foo already exists:", os.foo)
}
}

実行しましょう。

iris session iris -U IRISAPP
IRISAPP>do ##class(Article.Introduction2).Run()

IRISAPP>do ##class(Article.Introduction2).Run()
os.foo already exists: bar  

Pythonインタープリターだと、こんな感じになります。

import os

if not hasattr(os, 'foo'):
    os.foo = "bar"
else:
    print("os.foo already exists:", os.foo)

import os
if not hasattr(os, 'foo'):
    os.foo = "bar"
else:
    print("os.foo already exists:", os.foo)

出力:

os.foo already exists: bar # only printed once

いかがでしょうか。

今後の内容 :

  • Pep8
  • モジュール
  • ダンダーメソッド
  • IRISでPythonを動かす
  • ...
0
0 16
記事 Toshihiko Minamoto · 10月 28, 2025 3m read

img

この記事では、マジックメソッドとしても知られるPythonダンダーメソッドについて簡単に解説します。

ダンダーメソッドとは?

ダンダーメソッドは、始めと終わりに2つのアンダースコア(__)が付いているPythonの特殊メソッドです。 このメソッドを使用することで、加算や減算、文字列表現など、組み込みの操作に対するオブジェクトの動作を定義することができます。

よくあるダンダーメソッドには、次が含まれます。

  • __init__(self, ...):オブジェクトの作成時に呼び出されます。
    • ObjectScriptの %OnNew メソッドに似ています
  • __str__(self):オブジェクトを文字列として表現するために、str() 組み込み関数と print によって呼び出されます。
  • __repr__(self):デバッグ用のオブジェクトを表現するために、repr() 組み込み関数によって呼び出されます。
  • __add__(self, other)+ 演算子が使用される際に呼び出されます。
  • __len__(self):オブジェクトの長さを返すために、len() 組み込み関数によって呼び出されます。
  • __getitem__(self, key):インデックス構文を使用してコレクションからアイテムを取得するために呼び出されます。
  • __setitem__(self, key, value):インデックス構文を使用してコレクション内にアイテムを設定するために呼び出されます。
  • ... 他にもたくさんあります。

IRIS環境において、ダンダーメソッドが重要であり関連性があるのはなぜか?

Objectscriptでは、Pythonのようなシンタックスシュガーはありませんが、ダンダーメソッドを使用して同じような動作を実現できます。

例えば、インポートしたPythonモジュールにPythonのリストを返す関数があり、Objectscriptでそれを使用したいとします。 リスト内のアイテムにアクセスするには、__getitem__ ダンダーメソッドを使用する必要があります。

# src/python/article/dunder_example.py
def get_list():
    return [1, 2, 3, 4, 5]
Class Article.DunderExample Extends %RegisteredObject
{

ClassMethod Run()
{
    Set sys = ##class(%SYS.Python).Import("sys")
    do sys.path.append("/irisdev/app/src/python/article")
    set dunderExample = ##class(%SYS.Python).Import("dunder_example")
    set myList = dunderExample."get_list"()
    for i=0:1:myList."__len__"()-1 {
        write myList."__getitem__"(i), !
    }
}

}

実行しましょう。

iris session iris -U IRISAPP '##class(Article.DunderExample).Run()'

出力は以下のようになります。

1
2
3
4
5

これは、IRIS環境でPythonオブジェクトとやり取りするためにダンダーメソッドを使う方法を具体的に示しており、ObjectScript環境内で作業しながらPythonの機能を活用することができます。

ボーナス

ダンダーの優れた使い方の1つは、スクリプトがモジュールとしてインポートされた際にコードが実行されないようにするために、if __name__ == "__main__": ブロックをPythonスクリプトの最後に配置することです。

最初の記事で、スクリプトをインポートするとコードが実行されることを説明しました。 このブロックにより、スクリプトがインポートされたときではなく、直接実行されたときにのみ実行されるコードを定義できます。

例:

# src/python/article/dunder_example.py
def get_list():
    return [1, 2, 3, 4, 5]

if __name__ == "__main__":
    print(get_list())

まとめ

ダンダーメソッドを使えば、PythonのシンタックスシュガーでできることはObjectScriptでも可能です。

0
0 14
記事 Kosaku Ikeda · 10月 26, 2025 14m read

コミュニティの皆さんこんにちは。
 

ベクトル検索関連の処理が完全にノーマークだった私が、一先ず「やってみよう!」との事で、2つの動画のサンプルを実行してみました。
Pythonは初心者なので、アレな箇所があっても目をつぶっていただけると幸いです。

また、間違っている箇所があったら、ご指摘いただけると幸いです。


■参考にした動画

■参考にしたコミュニティ記事

【目的】

本記事では、動画で紹介された内容を実際にIRIS環境上で実行できるよう、具体的な環境構築とコーディングを記載致します。
コミュニティの皆さんが簡単に試せるようになれば幸いです。

またGithubにサンプルソースを配置しているので、必要な方は参考にして下さい。

【準備】

■作業環境

※環境作成方法に問題のない方は、読み飛ばしていただいて構いません。

項目 バージョン情報・他
OS WIndowsServer2019
IRIS IRIS Community 2025.2.0.227.0
Python 3.12.10
開発環境 VS Code 1.105.1
0
0 41
記事 Hiroshi Sato · 6月 22, 2025 1m read

.pyファイルの中でIRISのEmbedded Pythonを動作させる際にirispythonコマンドで実行する方法はドキュメント上で紹介されていましたので、以前より使用していました。

しかし、普通のpythonコマンドを使用するとうまく実行できなかったのですが、最近その謎(原因)が解けたので紹介します。

これは、Mac特有の問題である可能性が高くWindowsやLinuxでは何の問題もなく実行できるのかもしれません。

エラーは以下のようなエラーです。

  File "/opt/iris/lib/python/iris.py", line 34, in <module>
    from pythonint import *
ImportError: IrisSecureStart failed: IRIS_ATTACH (-21)

 

このエラーの原因は、シェルの実行ユーザーとirisのオーナーが異なることが原因とのことです。

Macで普通にIRISをインストールするとそのオーナーはrootです。

従ってpython3コマンドを実行する時にsudoコマンドでrootになる必要があるということです。

そして以下のような環境変数の設定も必要です。

3
0 78
記事 Mihoko Iijima · 10月 9, 2025 1m read

開発者の皆さん、こんにちは!

この記事では、Developer Hub にあるチュートリアルに新しいチュートリアル:InterSystems IRIS ベクトル検索を使用した RAG が追加されましたので内容をご紹介します。(準備不要でブラウザがあれば試せるチュートリアルです!)

このチュートリアルでは、生成 AI アプリケーションの精度向上に向けて、ベクトル検索と検索拡張生成(Retrieval Augmented Generation)の活用を体験できます。

具体的には、InterSystems IRIS のベクトル検索機能を活用し、生成 AI チャットボット向けのナレッジベースをサンプルコードを利用して作成します。

また、Streamlit を使用して作成したチャットボットを動かしながら、ナレッジベースの情報を追加することで生成 AI からの回答が変化していくことを確認していきます。

アカウント作成やログインも不要で  ボタンをクリックするだけで始められます👍

チュートリアルへのリンクは「開発者コミュニティのリソース」からも辿れます!

ぜひ、お試しください!​​​​​​

0
0 33
記事 Toshihiko Minamoto · 10月 7, 2025 9m read

コミュニティの皆さん、こんにちは。
この記事では、私のアプリケーションである iris-AgenticAI をご紹介します。

エージェンティック AI の登場により、人工知能が世界とやりとりする方法に変革的な飛躍をもたらし、静的なレスポンスが動的な目標主導の問題解決にシフトしています。 OpenAI の Agentic SDK を搭載した OpenAI Agents SDK を使用すると、抽象化をほとんど行わずに軽量で使いやすいパッケージでエージェンティック AI アプリを構築できます。 これは Swarm という前回のエージェントの実験を本番対応にアップグレードしたものです。
このアプリケーションは、人間のような適応性で複雑なタスクの推論、コラボレーション、実行を行える次世代の自律 AI システムを紹介しています。

アプリケーションの機能

  • エージェントループ  🔄 ツールの実行を自律的に管理し、結果を LLM に送信して、タスクが完了するまで反復処理するビルトインのループ。
  • Python-First 🐍 ネイティブの Python 構文(デコレーター、ジェネレーターなど)を利用して、外部の DSL を使用せずにエージェントのオーケストレーションとチェーンを行います。
  • ハンドオフ 🤝 専門化されたエージェント間でタスクを委任することで、マルチエージェントワークフローをシームレスに調整します。
  • 関数ツール ⚒️ @tool で Python 関数をデコレートすることで、エージェントのツールキットに即座に統合させます。
  • ベクトル検索(RAG) 🧠 RAG 検索のためのベクトルストアのネイティブ統合。
  • トレース 🔍 リアルタイムでエージェントワークフローの可視化、デバッグ、監視を行うためのビルトインのトレース機能(LangSmith の代替サービスとして考えられます)。
  • MCP サーバー 🌐 stdio と HTTP によるモデルコンテキストプロトコル(MCP)で、クロスプロセスエージェント通信を可能にします。
  • Chainlit UI 🖥️ 最小限のコードで対話型チャットインターフェースを構築するための統合 Chainlit フレームワーク。
  • ステートフルメモリ 🧠 継続性を実現し、長時間実行するタスクに対応するために、セッション間でチャット履歴、コンテキスト、およびエージェントの状態を保持します。

エージェント

エージェントは、アプリの主要な構成要素です。 エージェントは大規模言語モデル(LLM)で、instructions と tools で構成されています。 基本的な構成 以下は、構成されるエージェントの最も一般的なプロパティです。

Instructions: 開発者メッセージまたはシステムプロンプトとも呼ば出る指示。
model: LLM が使用するモデル。オプションとして model_settings を使用して、temperature や top_p など、モデルのチューニングパラメーターを構成できます。
tools: タスクを達成するためにエージェントが使用できるツール。

from agents import Agent, ModelSettings, function_tool

@function_tooldefget_weather(city: str) -> str:returnf"The weather in {city} is sunny"
agent = Agent(
    name="Haiku agent",
    instructions="Always respond in haiku form",
    model="o3-mini",
    tools=[get_weather],
)

エージェントの実行

Runner クラスを使ってエージェントを実行できます。 これには 3 つのオプションがあります。

  1. Runner.run(): 非同期で実行し、RunResult を返します。
  2. Runner.run_sync(): 非同期メソッドで、内部で .run() を実行します。
  3. Runner.run_streamed(): 非同期で実行し、RunResultStreaming を返します。 ストリーミングモードで LLM を呼び出し、イベントを受け取るたびにユーザーにストリーミングします。
from agents import Agent, Runner

asyncdefmain(): agent = Agent(name="Assistant", instructions="You are a helpful assistant")

result = <span class="hljs-keyword">await</span> Runner.run(agent, <span class="hljs-string">"Write a haiku about recursion in programming."</span>)
print(result.final_output)
<span class="hljs-comment"># Code within the code,</span>
<span class="hljs-comment"># Functions calling themselves,</span>
<span class="hljs-comment"># Infinite loop's dance.</span></code></pre>


エージェントアーキテクチャ

アプリケーションは 7 つの専門化されたエージェントで構成されています。

  1. Triage エージェント 🤖
    • 機能: ユーザー入力を受け取り、ハンドオフでタスクを委任する主要ルーター
    • : 「Show production errors(プロダクションエラーを表示)」は IRIS プロダクションエージェントに転送されます。
  2. ベクトル検索エージェント 🤖
    • 機能: IRIS 2025.1 リリースノートの内容を提供します(RAG 機能)
    • : 「Provide me summary of Release Notes(リリースノートの要約を提供)」はベクトル検索エージェントに転送されます。
  3. IRIS Dashboard エージェント 🤖
    • 機能: リアルタイムの管理ポータルメトリクスを提供します: plaintext Copy
      ApplicationErrors, CSPSessions, CacheEfficiency, DatabaseSpace, DiskReads,  
      DiskWrites, ECPAppServer, ECPDataServer, GloRefs, JournalStatus,  
      LicenseCurrent, LockTable, Processes, SystemUpTime, WriteDaemon, [...]
  4. IRIS 実行プロセスエージェント 🤖
    • 機能: アクティブなプロセスを次の詳細とともに監視します。
      • Process ID | Namespace | Routine | State | PidExternal
  5. IRIS Production エージェント 🤖
    • 機能: プロダクションの開始と停止の機能とともにプロダクションの詳細を提供します。
  6. WebSearch エージェント 🤖
    • 機能: API 統合によりコンテキストウェブ検索を実行します。
  7. Order エージェント 🤖
    • 機能: 注文 ID を使用して注文のステータスを取得します。


ハンドオフ

ハンドオフによって、タスクを別のエージェントに委任することができます。 これは特に、それぞれのエージェントが異なる分野に特化している場合に役立ちます。 たとえば、カスタマーサポートアプリには、注文ステータス、返金、FAQ などのそれぞれのタスクを専門的に処理するエージェントが実装されている場合があります。

Triage エージェントはこのアプリケーションのメインエージェントで、ユーザー入力に基づいて別のエージェントにタスクを委任するエージェントです。

#TRIAGE AGENT, Main agent receives user input and delegates to other agent by using handoffs
    triage_agent = Agent(
        name="Triage agent",
        instructions=(
            "Handoff to appropriate agent based on user query.""if they ask about Release Notes, handoff to the vector_search_agent.""If they ask about production, handoff to the production agent.""If they ask about dashboard, handoff to the dashboard agent.""If they ask about process, handoff to the processes agent.""use the WebSearchAgent tool to find information related to the user's query and do not use this agent is query is about Release Notes.""If they ask about order, handoff to the order_agent."
        ),
        handoffs=[vector_search_agent,production_agent,dashboard_agent,processes_agent,order_agent,web_search_agent]
    )


トレース

Agents SDK には、トレース機能が組み込まれており、エージェントの実行中にLLM の生成、ツールの呼び出し、ハンドオフ、ガードレール、カスタムイベントの発生など、イベントの包括的な記録を収集できます。 Traces ダッシュボードを使用すると、開発中と本番稼動時にワークフローのデバッグ、可視化、監視を行えます。
https://platform.openai.com/logs

image

 


アプリケーションのインターフェース

アプリケーションのワークフロープロセス
ベクトル検索エージェント

ベクトル検索エージェントは、「New in InterSystems IRIS 2025.1」のテキスト情報のデータがまだ存在しない場合に、そのデータを一度だけ自動的に IRIS Vector Store に取り込みます。  


以下のクエリを使用してデータを検索しましょう

SELECTid, embedding, document, metadata
FROM SQLUser.AgenticAIRAG

Triage エージェントはユーザー入力を受け取って、質問をベクトル検索エージェントに転送します。

IRIS Dashboard エージェント

Triage エージェントはユーザー入力を受け取って、質問を IRIS Dashboard エージェントに転送します。

IRIS Processes エージェント

Triage エージェントはユーザー入力を受け取って、質問を IRIS Processes エージェントに転送します。

IRIS Production エージェント

Production エージェントを使用して、プロダクションの開始と停止を行います。

Production エージェントを使用して、プロダクションの詳細を取得します。

Local エージェント

Triage エLocal ージェントはユーザー入力を受け取って、質問を Local Order エージェントに転送します。

WebSearch エージェント

ここでは、Triage エージェントは 2 つの質問を受け取って、WebSearch エージェントに転送します。

MCP Server アプリケーション

MCP Server は https://localhost:8000/sse で実行しています。

image
以下のコードで MCP Server を起動しています。

import os
import shutil
import subprocess
import time
from typing import Any
from dotenv import load_dotenv

load_dotenv()

#Get OPENAI Key, if not fond in .env then get the GEIMINI API KEY#IF Both defined then take OPENAI Key openai_api_key = os.getenv("OPENAI_API_KEY") ifnot openai_api_key: raise ValueError("OPENAI_API_KEY is not set. Please ensure to defined in .env file.")

ifname == "main": # Let's make sure the user has uv installedifnot shutil.which("uv"): raise RuntimeError( "uv is not installed. Please install it: https://docs.astral.sh/uv/getting-started/installation/" )

<span class="hljs-comment"># We'll run the SSE server in a subprocess. Usually this would be a remote server, but for this</span>
<span class="hljs-comment"># demo, we'll run it locally at http://localhost:8000/sse</span>
process: subprocess.Popen[Any] | <span class="hljs-keyword">None</span> = <span class="hljs-keyword">None</span>
<span class="hljs-keyword">try</span>:
    this_dir = os.path.dirname(os.path.abspath(__file__))
    server_file = os.path.join(this_dir, <span class="hljs-string">"MCPserver.py"</span>)

    print(<span class="hljs-string">"Starting SSE server at http://localhost:8000/sse ..."</span>)

    <span class="hljs-comment"># Run `uv run server.py` to start the SSE server</span>
    process = subprocess.Popen([<span class="hljs-string">"uv"</span>, <span class="hljs-string">"run"</span>, server_file])
    <span class="hljs-comment"># Give it 3 seconds to start</span>
    time.sleep(<span class="hljs-number">3</span>)

    print(<span class="hljs-string">"SSE server started. Running example...\n\n"</span>)
<span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:
    print(<span class="hljs-string">f"Error starting SSE server: <span class="hljs-subst">{e}</span>"</span>)
    exit(<span class="hljs-number">1</span>)

 

MCP Server には次のツールが備わっています。

  • IRIS 2025.1 リリースノートの詳細を提供(ベクトル検索)
  • IRIS 情報ツール
  • 天気チェックツール
  • シークレットワードの検索ツール(ローカル関数)
  • 加算ツール(ローカル関数)

MCP アプリケーションは  http://localhost:8001で実行しています。

 

MCP Server ベクトル検索(RAG)機能

MCP Server には InterSystems IRIS ベクトル検索インジェスト機能と検索拡張生成(RAG)機能が備わっています。


MCP Server の他の機能

MCP Server は、ユーザー入力に基づいて、適切なツールに動的にタスクを委任します。


詳細については、iris-AgenticAI の Open Exchange アプリケーションページをご覧ください。

以上です

0
0 26
記事 Mihoko Iijima · 8月 7, 2025 4m read

開発者の皆さん、こんにちは!

Windows 版 IRIS/IRIS for Health 2025.1 以降で Embedded Python をご利用いただく場合、Windows に Python のインストールが必要になりました。

以前のバージョンから Embedded Python をご利用いただいている場合は、新しいバージョンにアップグレードした後、Python のインストールと IRIS 側に必要な設定がありますのでご注意ください。

※ 2024.1 以前のバージョンでは、IRIS インストールと同時にインストールされる Python ご利用いただく必要があったため、Windows への Python インストールは不要でした。

補足:フレキシブル Python ランタイム機能の導入により、OS にインストールされた Python のバージョンを IRIS 側で指定できるようになりました。

詳細はドキュメントもご参照ください:フレキシブル Python ランタイム機能の概要

Embedded Python 利用までの手順は以下の通りです。

1) サポートする Python のバージョンを確認

サポートしている Python のバージョンを確認します。(Windows は、Python 3.9以降)

0
3 72
記事 Mihoko Iijima · 7月 3, 2025 4m read

これは InterSystems FAQ サイトの記事です。

InterSystems 製品では、ファイルオープン時に文字コードを指定すれば指定の文字コードで正しくファイルの中身を処理できます。

文字コードを指定しない場合、InterSystems 製品をインストールした OS に合わせて設定されたファイル I/O 用文字コードを利用してファイルをオープンします(Linux 系は UTF8、Windows は SJIS)。

また、文字列については文字コードが判明していれば $ZCONVERT() 関数を使用して指定文字コードで文字列を処理することができます。

 例)$ZCONVERT(文字列,"I","IRIS内文字コード")

文字コードが不明な場合、残念ながら InterSystems 製品だけでそのコードを判別することができないため、例えば Embedded Python で Python の chardet パッケージを使用して文字コード判別し、IRIS 内文字コードを取得しファイルオープン、文字列の文字コード変換をすることができます。

chardetパッケージについては、外部サイトですが参考となります。ぜひご参照ください。

参考ページ:[解決!Python]テキストファイルのエンコーディングを調べて、その内容を読み込むには(chardetパッケージ)

0
1 92
記事 Toshihiko Minamoto · 5月 27, 2025 14m read

次回の Python コンテストでは、Python を使用して IRIS をデータベースとして使用する簡単な REST アプリケーションを作成する方法についての小さなデモを作成しようと思います。 以下のツールを使用します。

  • FastAPI フレームワーク: 高パフォーマンス、学習しやすい、高速コーディング、プロダクション対応
  • SQLAlchemy: Python SQL ツールキットで、アプリケーション開発者が SQL の全性能と柔軟性を活用できるオブジェクトリレーションマッパーです。
  • Alembic: Python 用の SQLAlchemy データベースツールキットと使用する軽量のデータベース移行ツール。
  • Uvicorn: Python の ASGI ウェブサーバー実装。

環境の準備

バージョン 3.7 以降の Python がすでにインストール済みだと思います。 プロジェクトフォルダを作成し、その中に以下のコンテンツで requirements.txt ファイルを作成します。

fastapi==0.101.1
alembic==1.11.1
uvicorn==0.22.0
sqlalchemy==2.0.20
sqlalchemy-iris==0.10.5

Python で仮想環境を使用することをお勧めします。新しい環境を作成して有効化しましょう。

python -m venv env && source env/bin/activate

そして、依存関係をインストールします。

pip install -r requirements.txt

クイックスタート

FastAPI を使って最も単純な REST Api を作成しましょう。 これを行うには、app/main.py を作成します。

from fastapi import FastAPI

app = FastAPI( title='TODO Application', version='1.0.0', )

@app.get("/ping")asyncdefpong():return {"ping": "pong!"}

この時点で、アプリケーションを純分に起動して動作させることができます。 サーバーの起動には、uvicorn を使用します。

$ uvicorn app.main:app         
INFO:     Started server process [94936]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)

ping リクエストを発行できます。

$ curl http://localhost:8000/ping
{"ping":"pong!"}

FastAPI には API をテストできる UI が用意されています。

Docker 化環境

IRIS をアプリケーションに追加するには、コンテナーを使用します。 IRIS イメージはそのままで使用できますが、Python アプリケーション用の Docker イメージを作成する必要があります。 また、Dockerfile が必要です。

FROM python:3.11-slim-buster

WORKDIR /usr/src/app RUN --mount=type=bind,src=.,dst=.
pip install --upgrade pip &&
pip install -r requirements.txt
COPY . . ENTRYPOINT [ "/usr/src/app/entrypoint.sh" ]

コンテナー内でアプリケーションを起動するには、簡単な entrypoint.sh が必要です。

#!/bin/sh
# Run SQL Migrations, to make DB Schema up to date
alembic upgrade head

# Start Python application uvicorn app.main:app
--workers 1
--host 0.0.0.0
--port 8000 "$@"

実行フラグを忘れずに追加しましょう。

chmod +x entrypoint.sh

docker-compose.yml で IRIS と組み合わせます。

version:"3"services:  iris:    image:intersystemsdc/iris-community    ports:      -1972    environment:      -IRISUSERNAME=demo      -IRISPASSWORD=demo    healthcheck:      test:/irisHealth.sh      interval:5s  app:    build:.    ports:      -8000:8000    environment:      -DATABASE_URL=iris://demo:demo@iris:1972/USER    volumes:      -./:/usr/src/app    depends_on:      iris:        condition:service_healthy    command:      ---reload

ではビルドしましょう。

docker-compose build

最初のデータモデル

アプリケーションに IRIS データベースへのアクセスを宣言し、app/db.py ファイルを追加しましょう。このファイルによって データベースにアクセスできるように SQLAlchemy が構成されます。これは docker-compose.yml によって渡される URL で定義されます。これには後でアプリで使用するハンドラーがいくつか含まれています。

import os

from sqlalchemy import create_engine from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base from sqlalchemy.orm import sessionmaker

DATABASE_URL = os.environ.get("DATABASE_URL") ifnot DATABASE_URL: DATABASE_URL = "iris://demo:demo@localhost:1972/USER" engine = create_engine(DATABASE_URL, echo=True, future=True)

Base: DeclarativeMeta = declarative_base()

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

definit_db(): engine.connect()

defget_session(): session = SessionLocal() yield session

では、初の唯一のモデルをアプリケーションに定義しましょう。 ファイル app/models.py を作成して編集します。SQLAlchemy を使用して、Todo と言う、id、title、description の 3 つ列を持つモデルを定義します。

from sqlalchemy import Column, Integer, String, Text
from app.db import Base

classTodo(Base):tablename = 'todo' id = Column(Integer, primary_key=True, index=True) title = Column(String(200), index=True, nullable=False) description = Column(Text, nullable=False)

SQL の移行の準備

変化し続ける世界では、アプリケーションは将来的に改善されると考えるため、テーブル構造は最終的なものではなく、さらにテーブル、列、インデックスなどを追加できるとわかっています。 この場合の最善のシナリオは、SQL Migration ツールを使用することです。これは、アプリケーションのバージョンに応じてデータベースの現在の構造をアップグレードできるツールであり、何かが誤ってしまった場合には、これらのツールを使用することでダウングレードすることもできます。 このプロジェクトでは Python と SQLAlchemy を使用していますが、SQLAlchemy の作者は Alembic というツールを提供しており、ここではそれを使用します。

IRIS と、アプリケーションを含むコンテナーを起動する必要がありますが、この時点では、コマンドを実行できるように Bash する必要があります。

$ docker-compose run --entrypoint bash app
[+] Creating 2/0
 ✔ Network fastapi-iris-demo_default   Created                                                                                                                                                        0.0s 
 ✔ Container fastapi-iris-demo-iris-1  Created                                                                                                                                                        0.0s 
[+] Running 1/1
 ✔ Container fastapi-iris-demo-iris-1  Started                                                                                                                                                        0.1s 
root@7bf903cd2721:/usr/src/app# 

コマンド alembic init app/migrations を実行します。

root@7bf903cd2721:/usr/src/app# alembic init app/migrations
  Creating directory '/usr/src/app/app/migrations' ...  done
  Creating directory '/usr/src/app/app/migrations/versions' ...  done
  Generating /usr/src/app/app/migrations/README ...  done
  Generating /usr/src/app/app/migrations/script.py.mako ...  done
  Generating /usr/src/app/app/migrations/env.py ...  done
  Generating /usr/src/app/alembic.ini ...  done
  Please edit configuration/connection/logging settings in '/usr/src/app/alembic.ini' before proceeding.
root@7bf903cd2721:/usr/src/app#

これにより Alembic 構成が準備されたため、アプリケーションのニーズに適合するように修正する必要があります。 これを行うには app/migrations/env.py ファイルを編集します。 これはファイルの始まりに過ぎないため、更新する必要があります。sqlalchemy.urltarget_metadata を更新することに専念しましょう。 その以下の変更はありません。

import os
import urllib.parse
from logging.config import fileConfig

from sqlalchemy import engine_from_config from sqlalchemy import pool

from alembic import context

# this is the Alembic Config object, which provides# access to the values within the .ini file in use. config = context.config

DATABASE_URL = os.environ.get("DATABASE_URL")

decoded_uri = urllib.parse.unquote(DATABASE_URL) config.set_main_option("sqlalchemy.url", decoded_uri)

# Interpret the config file for Python logging.# This line sets up loggers basically.if config.config_file_name isnotNone: fileConfig(config.config_file_name)

# add your model's MetaData object here# for 'autogenerate' supportfrom app.models import Base target_metadata = Base.metadata # target_metadata = None

すでにモデルが存在するため、コマンド alembic revision --autogenerate で移行を作成する必要があります。

root@7bf903cd2721:/usr/src/app# alembic revision --autogenerate
INFO  [alembic.runtime.migration] Context impl IRISImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'todo'
INFO  [alembic.autogenerate.compare] Detected added index 'ix_todo_id' on '['id']'
INFO  [alembic.autogenerate.compare] Detected added index 'ix_todo_title' on '['title']'
  Generating /usr/src/app/app/migrations/versions/1e4d3b4d51ca_.py ...  done
root@7bf903cd2721:/usr/src/app# 
 
生成された移行を見てみましょう。

では、これをデータベースに適用しましょう。コマンド alembic upgrade head を使用します。ここで、head は最新バージョンにアップグレードするためのキーワードです。

root@7bf903cd2721:/usr/src/app# alembic upgrade head
INFO  [alembic.runtime.migration] Context impl IRISImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 1e4d3b4d51ca, empty message
 
Downgrade
アプリケーションのアップグレード中に元に戻す必要があることが分かった場合に、例えば 1 つ前のリビジョンにデータベースをダウングレードするには head-1 とします。
root@7bf903cd2721:/usr/src/app# alembic downgrade head-1
INFO  [alembic.runtime.migration] Context impl IRISImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running downgrade 1e4d3b4d51ca -> , empty message

and to completely downgrade back to an empty state, use keyword base

現在の状態をいつでも確認できます。いくつかの移行が欠落している場合にはその情報を得られます。

root@7bf903cd2721:/usr/src/app# alembic check
INFO  [alembic.runtime.migration] Context impl IRISImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
No new upgrade operations detected.

データをアクセス可能にする

REST に戻り、実行させる必要があります。現在のコンテナーを終了し、アプリサービスを通常どおり実行すると、uvicorn には --reload フラグが設定されているため、Python ファイル内の変更をチェックし、変更がある場合には再起動されます。

$ docker-compose up app
[+] Running 2/0
 ✔ Container fastapi-iris-demo-iris-1  Running                                                                                                                                                        0.0s 
 ✔ Container fastapi-iris-demo-app-1   Created                                                                                                                                                        0.0s 
Attaching to fastapi-iris-demo-app-1, fastapi-iris-demo-iris-1
fastapi-iris-demo-app-1   | INFO  [alembic.runtime.migration] Context impl IRISImpl.
fastapi-iris-demo-app-1   | INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
fastapi-iris-demo-app-1   | INFO:     Will watch for changes in these directories: ['/usr/src/app']
fastapi-iris-demo-app-1   | INFO:     Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
fastapi-iris-demo-app-1   | INFO:     Started reloader process [8] using StatReload
fastapi-iris-demo-app-1   | INFO:     Started server process [10]
fastapi-iris-demo-app-1   | INFO:     Waiting for application startup.
fastapi-iris-demo-app-1   | INFO:     Application startup complete.

FastAPI は Pydantic プロジェクトを使用してデータスキーマを宣言しているため、それも必要です。app/schemas.py を作成しましょう。列は models.py と同じですが、単純な Python フォームを使用します。

from pydantic import BaseModel

classTodoCreate(BaseModel): title: str description: str

classTodo(TodoCreate): id: int

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Config</span>:</span>
    from_attributes = <span class="hljs-keyword">True</span>

SQLAlchemy ORM を使ってデータベースを操作する app/crud.py で CRUD 操作を宣言します。

from sqlalchemy.orm import Session
from . import models, schemas

defget_todos(db: Session, skip: int = 0, limit: int = 100):return db.query(models.Todo).offset(skip).limit(limit).all()

defcreate_todo(db: Session, todo: schemas.TodoCreate): db_todo = models.Todo(**todo.dict()) db.add(db_todo) db.commit() db.refresh(db_todo) return db_todo

そして最後に、app/main.py を更新し、ToDo を読み取って作成するルートを追加できます。

from fastapi import FastAPI, Depends
from .db import init_db, get_session
from . import crud, schemas

app = FastAPI( title='TODO Application', version='1.0.0', )

@app.on_event("startup")defon_startup(): init_db()

@app.get("/ping")asyncdefpong():return {"ping": "pong!"}

@app.get("/todo", response_model=list[schemas.Todo])asyncdefread_todos(skip: int = 0, limit: int = 100, session=Depends(get_session)): todos = crud.get_todos(session, skip=skip, limit=limit) return todos

@app.post("/todo", response_model=schemas.Todo)asyncdefcreate_todo(todo: schemas.TodoCreate, session=Depends(get_session)):return crud.create_todo(db=session, todo=todo)

これに応じてドキュメント ページが更新され、実際に操作できるようになりました。

 
試してみましょう。
新しい ToDo を追加します。

その内容を確認しましょう。

IRIS で確認してみましょう。

─$ docker-compose exec iris irissqlcli iris+emb:///
Server:  IRIS for UNIX (Ubuntu Server LTS for ARM64 Containers) 2023.2 (Build 227U) Mon Jul 31 2023 17:43:25 EDT
Version: 0.5.4
[SQL]irisowner@/usr/irissys/:USER> .tables
+-------------------------+
| TABLE_NAME              |
+-------------------------+
| SQLUser.alembic_version |
| SQLUser.todo            |
+-------------------------+
Time: 0.043s
[SQL]irisowner@/usr/irissys/:USER> select * from todo
+----+-------+---------------------+
| id | title | description         |
+----+-------+---------------------+
| 1  | demo  | it's really working |
+----+-------+---------------------+
1 row in set
Time: 0.004s
[SQL]irisowner@/usr/irissys/:USER> select * from alembic_version
+--------------+
| version_num  |
+--------------+
| 1e4d3b4d51ca |
+--------------+
1 row in set
Time: 0.045s
[SQL]irisowner@/usr/irissys/:USER>

 

REST の作成において Python と FastAPI を簡単に使用していただけたなら幸いです。 このプロジェクトのソースコードは、GitHub の https://github.com/caretdev/fastapi-iris-demo にあります。

0
0 45
記事 Toshihiko Minamoto · 5月 20, 2025 7m read

Django フレームワークは長年学習したいと思ってきましたが、いつも他の差し迫ったプロジェクトが優先されてきました。 多くの開発者と同様に、機械学習においては Python を使用していますが、初めてウェブプログラミングについて学習したころは、PHP がまだまだ優勢でした。そのため、機械学習の作品を公開する目的でウェブアプリケーションを作成するための新しい複雑なフレームワークを選択する機会が訪れても、私は依然として PHP に目を向けていました。 ウェブサイトの構築には Laravel と呼ばれるフレームワークを使用してきましたが、この PHP フレームワークから最新の MVC(モデルビューコントローラー)というウェブプログラミングのパターンに出会いました。 さらに複雑なことに、私は最新の JavaScript フレームワークを使用してフロントエンドを構築するのを好んでいます。 React を使用するのがより一般的のようですが、私は Vue.js に一番慣れているため、このプロジェクトではそれを使用することにしました。

なぜ複雑なフレームワークを使用するのでしょうか? Django、Laravel、React、または Vue などのフレームワークを学習する際の最大の難関は何でしょうか?

答えは人それぞれですが、私は MVC フレームワークがアプリの構造化に関するガイドを非常に多く提供してくれるため、気に入っています。毎回、作り直す必要がありません。 初めはこういったフレームワークは制約が多くて難解に思えるかもしれませんが、構造に慣れてしまえば、新しい機能をより追加しやすいと思います。

問題は、物事があまりにも単純になりすぎる可能性があることです。 Django のようなフレームワークは、よく知られた概念に基づいているかもしれませんが、Django では特に馴染みのない名前と構造を持つ多くの省略形や仮定に依存しています。 私のアプリケーションでは、Django は API とすべてのウェブルーティングを処理しています。 新しい API エンドポイントを追加する場合は、views.py のファイルに関数を追加してから、urls.py ファイルに移動して、その関数をインポートするステートメントと、API エンドポイントが提供されている URL を定義する別のステートメントを追加する必要があります。 その後で、データを取得してユーザーに表示するか操作するために、そのエンドポイントをクエリする JavaScript を使って、フロントエンドの Vue コンポーネントを編集する必要があります。

プロジェクトのセットアップが完了したら、このような機能の追加は迅速に行えます。 約 4 行のコードを追加するだけで、HTTP リクエストを処理し、必要なデータを JSON 形式で返すように、views.py ファイルの新しい関数に必要なロジックに集中できます。 難しいのは、それらのファイルが何であるか、そしてそれらがどのように連携してアプリケーション全体を作り上げるかを学ぶことです。

Django のようなフレームワークを学習するには、実際に動作する例を探して、データのフローを感じ取れる小さな変更を適用して見るのが最適な方法だと思います。 概念が明確になり始めて理解できるようになってきたら、ドキュメントを参考にしましょう。 AI モデルにコードを説明してもらい、様々な標準ファイルがフレームワークでどのように動作するかを尋ねましょう。 これらのツールが、長期的には時間を節約し、アプリケーションの保守と更新を容易にする方法として登場したことにすぐに気づくでしょう。 Django と Vue フレームワークには標準の構造があるため、後で戻ってきても、なぜ特定の方法でコーディングしたのかをすぐに理解でき、作業についての理解を再び深めやすくなっているでしょう。 また、アプリケーションの基本構造に慣れているため、他の人のアプリケーションを理解し、主な機能を把握するのもより簡単です。

では、これから始めようとしている人の支援となる Django の基礎とは何でしょうか? 私にとっては、最初に理解すべきことは、Django プロジェクトは Django の新規プロジェクトを作成するコマンドの実行によって 生成され、これによって構築を開始するために使用できる「基本プロジェクト」を構成する一連の基本ファイルとフォルダが生成されるということです。 プロジェクトフォルダには、プロジェクト全体に適用される設定を含むいくつかの Python ファイルがあります。 頻繫にアクセスする重要なフォルダは、すべての設定が含まれる settings.py と、urls.py です。 「Django はどのようにして静的ファイルを配置する場所を決定しているのか」といった疑問がある場合、その答えは通常 settings.py のどこかにあります。 アプリケーションに新しい URL を追加する場合は、urls.py ファイルを更新する必要があります。

これらのプロジェクトレベルのファイルと共に、プロジェクト内のアプリごとにフォルダを作成します。 これらのアプリは登録されている必要があります。つまり、 settings.py ファイルで名前を付ける必要があります。 プロジェクト内のメインのアプリフォルダはドキュメントと呼ばれます。 どのフォルダ内には、models.py ファイル、serializer.py ファイル、views.py ファイルがあります。 ファイルは他にもありますが、これらが重要な 3 つのファイルです。

models.py 内には、Document オブジェクトとそのフィールドを指定します。 Document オブジェクトに保管する予定の情報を保存するために必要なスキーマを使って IRIS データベースに Documents テーブルを作成するのは、Django に任せられます。 私の models.py ファイルでは、Documents には 255 文字以内の名前、大量のテキストであるコンテンツフィールド、ベクトルが補完されるデータベース名(別のテキストフィールド)、埋め込みタイプ(別のテキストフィールド)、および数値で表現されるベクトル埋め込みの次元が含まれることを指定しています。 これらの定義を使用することで、Fjango は必要な列タイプで必要なデータベーステーブルを作成します。 すると、データベースへのオブジェクトの保存は、Document.save() だけで完了です。

serializer.py ファイル内には、オブジェクトと JSON の変換方法に関する定義が含まれます。 基本的なユースケースでは、これを定義する標準的な方法があり、このプロジェクトで確認できます。

では、Django の核心である views.py ファイルを確認しましょう。 ここに、HTTP リクエストを受け取って、HTTP レスポンス全体、または JSON API の場合は JSON API レスポンスなどのデータを返す関数を定義します。 つまり、Django ではウェブページ全体を制作して、アプリのフロントエンドとしても使用することも、JSON データのみを提供して、フロントエンドを全く別のプラットフォームで構築することもできます。

最初は、一見恣意的なファイルや規則をすべて使用するのは面倒に感じるかもしれませんが、そうすることでアプリケーションが動作し始め、HTTP リクエストを処理して、レスポンスとして正しいデータを提供するようになることが分かれば、新しい機能を構築し続けるのが非常に楽しくなります。 HTTP リクエストを処理するオブジェクト、ウェブルート、および関数を 1 つ定義すれば、2 つ目、そして 3 つ目を簡単に定義してアプリケーションに機能を追加できるようになります。

私のプロジェクトは、github: https://github.com/grongierisc/iris-django-template にある @Guillaume Rongier が作成した Iris Django Template をフォークしたものです。

このテンプレートには Django のみが含まれており、Django フレームワークの学習に非常に役立ちました。私が行った主な追加項目の 1 つは、Tailwind CSS を使用した Vue.js の追加です。最新の JavaScript フレームワークをこのパッケージに統合して、IRIS で実行する単一ページのアプリケーションを作成できます。 単一ページのアプリケーションは、xhr リクエストを送信して JSON データを取得し、完全に再読み込みすることなく動的にページを更新する JavaScript アプリケーションです。 これには長所と短所がありますが、最新のウェブ開発の特徴です。

RAG と IRIS 上のベクトルストアの例としてだけでなく、Vue.js と Tailwind を使って IRIS 上に最新の柔軟なウェブアプリケーションを簡単に素早く作成する目的で Django を使用するためのテンプレートとして、私のプロジェクトを確認することをお勧めします。 リポジトリはこちらの GitHub にあります: https://github.com/mindfulcoder49/iris-django-template

ご質問があれば、ぜひお答えします。このプロジェクトを独自のユースケースに適合しようとするする際に問題が発生した場合は、私の洞察を提供いたします。

0
0 63
記事 Tomoko Furuzono · 4月 17, 2025 1m read

これは、InterSystems FAQサイトの記事です。


メソッドの実装に使用する言語を明示する場合は、下記のようにメソッドキーワードで「Language=~~~」と指定します。

Method name(formal_spec) As returnclass [ Language = language ]
{    //implementation }

 指定できるLanguageの値は下記のとおりです。

  • objectscript (既定) — ObjectScript
  • python — 組み込み Python
  • tsql — Transact-SQL
  • ispl — Informix ストアド・プロシージャ言語

ドキュメント:Language (メソッド・キーワード)

上記の通り、ObjectScriptで記載する場合は、「Language=objectscript」と指定します。
但し、CSP内の<SCRIPT>タグ内で指定する場合は、下記の通り、「LANGUAGE=’cache’」と指定することにご注意ください。

<SCRIPT LANGUAGE='cache', ~~~>

ドキュメント:<SCRIPT>  

※CSPページは、IRISでは非推奨の機能です。

0
0 57
記事 Toshihiko Minamoto · 4月 11, 2025 10m read

django_logo

説明

これは、ネイティブウェブアプリケーションとして IRIS にデプロイできる Django アプリケーションのテンプレートです。

インストール

  1. リポジトリをクローンする
  2. 仮想環境を作成する
  3. 要件をインストールする
  4. docker-compose ファイルを実行する
git clone
cd iris-django-template
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
docker-compose up

使用法

ベース URL は http://localhost:53795/django/ です。

エンドポイント

  • /iris - IRISAPP ネームスペースに存在する上位 10 個のクラスを持つ JSON オブジェクトを返します。
  • /interop - IRIS の相互運用性フレームワークをテストするための ping エンドポイント。
  • /api/posts - Post オブジェクトの単純な CRUD エンドポイント。
  • ``/api/comments` - Comment オブジェクトの単純な CRUD エンドポイント。

このテンプレートからの開発方法

WSGI 導入記事をご覧ください: wsgi-introduction

概要: セキュリティポータルで DEBUG フラグをトグルすると、開発作業の過程で変更内容がアプリケーションに反映されるようになります。

コードの説明

Django アプリケーションは次のように構造化されています。

  • app - Django プロジェクトフォルダ
    • app - 構成用の Django アプリフォルダ
      • settings.py - Django の設定ファイル
      • urls.py - ビューを URL に接続する Django URL 構成ファイル
      • wsgi.py - Django WSGI ファイル
      • asgi.py - Django ASGI ファイル
    • community - コミュニティアプリの Django アプリフォルダ、Post と Comment オブジェクトでの CRUD 操作
      • models.py - Post と Comment オブジェクトの Django モデルファイル
      • views.py - Post と Comment オブジェクトにアクセスするための Django ビューファイル
      • serializers.py - Post と Comment オブジェクトの Django シリアライザーファイル
      • admin.py - 管理インターフェースに CRUD 操作を追加する Django 管理ファイル
      • migrations - データベースを構築するための Django マイグレーションフォルダ
      • fixtures - Django fixtures フォルダデモデータ
    • sqloniris - IRIS アプリでの SQL に使用する Django アプリフォルダ
      • views.py - IRISAPP ネームスペースをクエリするための Django ビューファイル
      • apps.py - Django アプリ構成ファイル
    • interop - 相互運用性アプリ用の Django アプリフォルダ
      • views.py - 相互運用性フレームワークをテストするための Django ビューファイル
      • apps.py - Django アプリ構成ファイル
    • manage.py - Django 管理ファイル

app/settings.py

このファイルには、アプリケーションの Django 設定が含まれます。

...

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'community',
    'sqloniris',
    'interop',
    'rest_framework'
]

...

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
    ],
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 20
}

...

DATABASES = {
    "default": {
        "ENGINE": "django_iris",
        "EMBEDDED": True,
        "NAMESPACE": "IRISAPP",
        "USER":"SuperUser",
        "PASSWORD":"SYS",
    }
}

一部の重要な設定:

  • INSTALLED_APPS - Django プロジェクトにインストール済みのアプリのリストが含まれます。
    • community - Post と Comment オブジェクトでの CRUD 操作用 Django アプリ。
    • sqloniris - IRIS での SQL 操作に使用する Django アプリ。
    • interop - 相互運用性操作用の Django アプリ。
    • rest_framework - REST API 用の Django REST フレームワーク。
  • REST_FRAMEWORK - Django REST フレームワークの設定が含まれます。
    • DEFAULT_PERMISSION_CLASSES - 認証済みのユーザーのみが CRUD 操作を実行できます。
    • DEFAULT_PAGINATION_CLASS - REST API のページネーションクラス。
  • DATABASES - IRIS データベース接続の設定が含まれます。
    • ここでは、django_iris エンジンを使って IRIS データベースに接続しています。

app/urls.py

このファイルには、Django アプリケーションの URL 構成が含まれます。

from django.contrib import admin
from django.urls import path,include
from rest_framework import routers
from community.views import PostViewSet, CommentViewSet
from sqloniris.views import index
from interop.views import index as interop_index

router = routers.DefaultRouter()
router.register(r'posts', PostViewSet)
router.register(r'comments', CommentViewSet)


urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),
    path('iris/', index),
    path('interop/', interop_index)
]
  • router - REST API のデフォルトのルーターが含まれます。
  • routeer.register - Post と Comment ビューセットをルーターに登録します。
  • urlpatterns - Django アプリケーションの URL パターンが含まれます。
    • /admin/ - Django 管理インターフェース。
    • /api/ - Post と Comment オブジェクトの REST API。
    • /iris/ - IRIS エンドポイントでの SQL。
    • /interop/ - 相互運用性エンドポイント。

app/wsgi.py

このファイルには、Django アプリケーションの WSGI 構成が含まれます。

これが、Django アプリケーションを実行するために IRIS に提供する必要のあるファイルです。

Security->Applications->Web Applications セクションで、このファイルへのパスを指定する必要があります。

  • アプリケーション名
    • app.wsgi
  • コーラブル名
    • application
  • WSGI アプリディレクトリ
    • /irisdev/app/app

community/models.py

このファイルには、Post と Comment オブジェクトの Django モデルが含まれます。

from django.db import models

# Create your models here.
class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

class Comment(models.Model):
    content = models.TextField()
    post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
  • Post - Post オブジェクトのモデル。
    • title - 投稿のタイトル。
    • content - 投稿のコンテンツ。
  • Comment - Comment オブジェクトのモデル。
    • content - コメントのコンテンツ。
    • post - Post オブジェクトの外部キー。
    • related_name - コメントの関連名。

community/seializers.py

このファイルには、Post と Comment オブジェクトの Django シリアライザーが含まれます。

Django REST フレームワークでは、Django モデルを JSON オブジェクトにシリアル化できます。

from rest_framework import serializers
from community.models import Post, Comment

class PostSerializer(serializers.ModelSerializer):
    class Meta:
        model = Post
        fields = ('id', 'title', 'content', 'comments')

class CommentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Comment
        fields = ('id', 'content', 'post')
  • PostSerializer - Post オブジェクトのシリアライザー。
  • CommentSerializer - Comment オブジェクトのシリアライザー。
  • fields - シリアル化されるフィールド。

community/views.py

このファイルには、Post と Comment オブジェクトの Django ビューが含まれます。

Django REST フレームワークを使て、Django モデルの CRUD 操作を作成できます。

from django.shortcuts import render
from rest_framework import viewsets

# Import the Post and Comment models
from community.models import Post, Comment

# Import the Post and Comment serializers
from community.serializers import PostSerializer, CommentSerializer

# Create your views here.
class PostViewSet(viewsets.ModelViewSet):
    queryset = Post.objects.all()
    serializer_class = PostSerializer

class CommentViewSet(viewsets.ModelViewSet):
    queryset = Comment.objects.all()
    serializer_class = CommentSerializer
  • PostViewSet - Post オブジェクトのビューセット。
  • CommentViewSet - Comment オブジェクトのビューセット。
  • queryset - ビューセットのクエリセット。
  • serializer_class - ビューセットのシリアライザークラス。

sqloniris/views.py

このファイルには、IRIS 操作における SQL の Django ビューが含まれます。

from django.http import JsonResponse

import iris

def index(request):
    query = "SELECT top 10 * FROM %Dictionary.ClassDefinition"
    rs = iris.sql.exec(query)
    # Convert the result to a list of dictionaries
    result = []
    for row in rs:
        result.append(row)
    return JsonResponse(result, safe=False)
  • index - IRIS 操作における SQL のビュー。
  • query - IRIS データベースで実行される SQL クエリ。
  • rs - クエリの結果セット。
  • result - 結果セットからのリストのリスト。
  • JsonResponse - ビューの JSON レスポンス。リストのリスト表示を許可するには safe を False に設定します。

interop/views.py

このファイルには、相互運用性操作における SQL の Django ビューが含まれます。

from django.http import HttpResponse

from grongier.pex import Director

bs = Director.create_python_business_service('BS')

def index(request):
    result = bs.on_process_input(request)
    return HttpResponse(result, safe=False)
  • bs - Director クラスを使用して作成されるビジネスサービスオブジェクト。
  • index - 相互運用性操作のビュー。
  • result - ビジネスサービスの結果。

注: コードを単純化するために JsonResponse は使用しません。JSON オブジェクトを返す場合は使用できます。

トラブルシューティング

スタンドアロンモードで Django アプリケーションを実行する方法

スタンドアロンモードで Django アプリケーションを実行するには、以下のコマンドを使用できます。

cd /irisdev/app/app
python3 manage.py runserver 8001

これは、デフォルトのポート 8001 で Django アプリケーションを実行します。

注: このコマンドを実行するには、コンテナー内にいる必要があります。

docker exec -it iris-django-template-iris-1 bash

IRIS でアプリケーションを再起動する

DEBUG モードでアプリケーションに複数の呼び出しを行うと、変更はアプリケーションに反映されます。

IRIS 管理ポータルへのアクセス方法

http://localhost:53795/csp/sys/UtilHome.csp に移動すると、IRIS 管理ポータルにアクセスできます。

このテンプレートをローカルで実行する

これには、マシンに IRIS がインストールされている必要があります。

次に、IRISAPP というネームスペースを作成する必要があります。

要件をインストールします。

# Move to the app directory
cd /irisdev/app/app

# python manage.py flush --no-input
python3 manage.py migrate
# create superuser
export DJANGO_SUPERUSER_PASSWORD=SYS
python3 manage.py createsuperuser --no-input --username SuperUser --email admin@admin.fr

# load demo data
python3 manage.py loaddata community/fixtures/demo.json

# collect static files
python3 manage.py collectstatic --no-input --clear

# init iop
iop --init

# load production
iop -m /irisdev/app/app/interop/settings.py

# start production
iop --start Python.Production

静的ファイルの配信方法

Django アプリケーションで静的ファイルを配信するには、以下のコマンドを使用できます。

cd /irisdev/app
python3 manage.py collectstatic

これは、Django アプリケーションから静的ファイルを収集して、/irisdev/app/static ディレクトリに配信します。

IRIS で静的ファイルを公開するには、Security->Applications->Web Applications セクションを構成します。

web_applications

0
0 37
InterSystems公式 Seisuke Nakahashi · 4月 3, 2025

IRIS 2024.3 で発生する2つの製品障害が確認されました。お使いの環境が該当する場合は、それぞれの解決方法にしたがってご対応いただきますよう、よろしくお願いします。

0
0 45
記事 Toshihiko Minamoto · 3月 27, 2025 8m read

fastapi_logo

説明

これは、ネイティブウェブアプリケーションとして IRIS にデプロイできる FastAPI アプリケーションのテンプレートです。

インストール

  1. リポジトリをクローンする
  2. 仮想環境を作成する
  3. 要件をインストールする
  4. docker-compose ファイルを実行する
git clone
cd iris-fastapi-template
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
docker-compose up

使用法

ベース URL は http://localhost:53795/fastapi/ です。

エンドポイント

  • /iris - IRISAPP ネームスペースに存在する上位 10 個のクラスを持つ JSON オブジェクトを返します。
  • /interop - IRIS の相互運用性フレームワークをテストするための ping エンドポイント。
  • /posts - Post オブジェクトの単純な CRUD エンドポイント。
  • /comments - Comment オブジェクトの単純な CRUD エンドポイント。

このテンプレートからの開発方法

WSGI 導入記事をご覧ください: wsgiサポートの概要

概要: セキュリティポータルで DEBUG フラグをトグルすると、開発作業の過程で変更内容がアプリケーションに反映されるようになります。

コードの説明

app.py

これは FastAPI アプリケーションのメインのファイルです。 FastAPI アプリケーションとルートが含まれます。

from fastapi import FastAPI, Request

import iris

from grongier.pex import Director

# import models
from models import Post, Comment, init_db
from sqlmodel import Session,select

app = FastAPI()

# create a database engine
url = "iris+emb://IRISAPP"
engine = init_db(url)
  • from fastapi import FastAPI, Request - FastAPI クラスト Request クラスをインポートします。
  • import iris - IRIS モジュールをインポートします。
  • from grongier.pex import Director: Flask アプリを IRIS 相互運用性フレームワークにバインドする Director クラスをインポートします。
  • from models import Post, Comment, init_db - モデルと init_db 関数をインポートします。
  • from sqlmodel import Session,select - Session クラスと sqlmodel モジュールの選択された関数をインポートします。
  • app = FastAPI() - FastAPI アプリケーションを作成します。
  • url = "iris+emb://IRISAPP" - IRIS ネームスペースの URL を定義します。
  • engine = init_db(url) - sqlmodel ORM のデータベースエンジンを作成します。

models.py

このファイルには、アプリケーションのモデルが含まれます。

from sqlmodel import Field, SQLModel, Relationship, create_engine

class Comment(SQLModel, table=True):
    id: int = Field(default=None, primary_key=True)
    post_id: int = Field(foreign_key="post.id")
    content: str
    post: "Post" = Relationship(back_populates="comments")

class Post(SQLModel, table=True):
    id: int = Field(default=None, primary_key=True)
    title: str
    content: str
    comments: list["Comment"] = Relationship(back_populates="post")

説明することは特にありません。外部キーとリレーションによる単なるモデルの定義です。

init_db 関数は、データベースエンジンの作成に使用されます。

def init_db(url):

    engine = create_engine(url)

    # create the tables
    SQLModel.metadata.drop_all(engine)
    SQLModel.metadata.create_all(engine)

    # initialize database with fake data
    from sqlmodel import Session

    with Session(engine) as session:
        # Create fake data
        post1 = Post(title='Post The First', content='Content for the first post')
        ...
        session.add(post1)
        ...
        session.commit()

    return engine
  • engine = create_engine(url) - データベースエンジンを作成します。
  • SQLModel.metadata.drop_all(engine) - すべてのテーブルをドロップします。
  • SQLModel.metadata.create_all(engine) - すべてのテーブルを作成します。
  • with Session(engine) as session: - データベースを操作するためのセッションを作成します。
  • post1 = Post(title='Post The First', content='Content for the first post') - Post オブジェクトを作成します。
  • session.add(post1) - Post オブジェクトをセッションに追加します。
  • session.commit() - 変更内容をデータベースにコミットします。
  • return engine - データベースエンジンを返します。

/iris エンドポイント

######################
# IRIS Query example #
######################

@app.get("/iris")
def iris_query():
    query = "SELECT top 10 * FROM %Dictionary.ClassDefinition"
    rs = iris.sql.exec(query)
    # Convert the result to a list of dictionaries
    result = []
    for row in rs:
        result.append(row)
    return result
  • @app.get("/iris") - /iris エンドポイントの GET ルートを定義します。
  • query = "SELECT top 10 * FROM %Dictionary.ClassDefinition" - IRIS ネームスペースで上位 10 個のクラスを取得するクエリを定義します。
  • rs = iris.sql.exec(query) - クエリを実行します。
  • result = [] - 結果を保存する空のリストを作成します。
  • for row in rs: - 結果セットを反復処理します。
  • result.append(row) - 結果リストを行にアペンドします。
  • return result - 結果リストを返します。

/interop エンドポイント

########################
# IRIS interop example #
########################
bs = Director.create_python_business_service('BS')

@app.get("/interop")
@app.post("/interop")
@app.put("/interop")
@app.delete("/interop")
def interop(request: Request):
    
    rsp = bs.on_process_input(request)

    return rsp

  • bs = Director.create_python_business_service('BS') - Python ビジネスサービスを作成します。
    • ビジネスサービスの複数のインスタンスを防止するために、ルート定義の外に作成する必要があります。
  • @app.get("/interop") - /interop エンドポイントの GET ルートを定義します。
  • @app.post("/interop") - /interop エンドポイントの POST ルートを定義します。
  • ...
  • def interop(request: Request): - ルートハンドラーを定義します。
  • rsp = bs.on_process_input(request) - ビジネスサービスの on_process_input メソッドを呼び出します。
  • return rsp - レスポンスを返します。

/posts エンドポイント

############################
# CRUD operations posts    #
############################

@app.get("/posts")
def get_posts():
    with Session(engine) as session:
        posts = session.exec(select(Post)).all()
        return posts
    
@app.get("/posts/{post_id}")
def get_post(post_id: int):
    with Session(engine) as session:
        post = session.get(Post, post_id)
        return post
    
@app.post("/posts")
def create_post(post: Post):
    with Session(engine) as session:
        session.add(post)
        session.commit()
        return post

このエンドポイントは、Post オブジェクトで CRUD 操作を実行するために使用されます。

説明することは特にありません。すべての投稿を取得し、ID で投稿を取得し、投稿を作成するためのルートの定義です。

すべては sqlmodel ORM を使って行われます。

/comments エンドポイント

############################
# CRUD operations comments #
############################


@app.get("/comments")
def get_comments():
    with Session(engine) as session:
        comments = session.exec(select(Comment)).all()
        return comments
    
@app.get("/comments/{comment_id}")
def get_comment(comment_id: int):
    with Session(engine) as session:
        comment = session.get(Comment, comment_id)
        return comment
    
@app.post("/comments")
def create_comment(comment: Comment):
    with Session(engine) as session:
        session.add(comment)
        session.commit()
        return comment

このエンドポイントは、Comment オブジェクトで CRUD 操作を実行するために使用されます。

説明することは特にありません。すべてのコメントを取得し、ID でコメントを取得し、コメントを作成するためのルートの定義です。

すべては sqlmodel ORM を使って行われます。

トラブルシューティング

スタンドアロンモードで FastAPI アプリケーションを実行する方法

以下のコマンドを使用して、いつでもスタンドアロンの Flask アプリケーションを実行できます。

python3 /irisdev/app/community/app.py

注: このコマンドを実行するには、コンテナー内にいる必要があります。

docker exec -it iris-fastapi-template-iris-1 bash

IRIS でアプリケーションを再起動する

DEBUG モードでアプリケーションに複数の呼び出しを行うと、変更はアプリケーションに反映されます。

IRIS 管理ポータルへのアクセス方法

http://localhost:53795/csp/sys/UtilHome.csp に移動すると、IRIS 管理ポータルにアクセスできます。

このテンプレートをローカルで実行する

これには、マシンに IRIS がインストールされている必要があります。

次に、IRISAPP というネームスペースを作成する必要があります。

要件をインストールします。

IoP のインストール:

#init iop
iop --init

# load production
iop -m /irisdev/app/community/interop/settings.py

# start production
iop --start Python.Production

セキュリティポータルでアプリケーションを構成します。

0
0 75
記事 Toshihiko Minamoto · 2月 27, 2025 7m read

Flask_logo

説明

これは、ネイティブウェブアプリケーションとして IRIS にデプロイできる Flask アプリケーションのテンプレートです。

インストール

  1. リポジトリをクローンする
  2. 仮想環境を作成する
  3. 要件をインストールする
  4. docker-compose ファイルを実行する
git clone
cd iris-flask-template
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
docker-compose up

使用法

ベース URL は http://localhost:53795/flask/ です。

エンドポイント

  • /iris - IRISAPP ネームスペースに存在する上位 10 個のクラスを持つ JSON オブジェクトを返します。
  • /interop - IRIS の相互運用性フレームワークをテストするための ping エンドポイント。
  • /posts - Post オブジェクトの単純な CRUD エンドポイント。
  • /comments - Comment オブジェクトの単純な CRUD エンドポイント。

このテンプレートからの開発方法

WSGI 導入記事をご覧ください: wsgi-introduction

概要: セキュリティポータルで DEBUG フラグをトグルすると、開発作業の過程で変更内容がアプリケーションに反映されるようになります。

コードの説明

app.py

これはアプリケーションのメインのファイルです。 Flask アプリケーションとエンドポイントが含まれます。

from flask import Flask, jsonify, request
from models import Comment, Post, init_db

from grongier.pex import Director

import iris

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'iris+emb://IRISAPP'

db = init_db(app)
  • from flask import Flask, jsonify, request: Flask ライブラリをインポートします。
  • from models import Comment, Post, init_db: モデルとデータベース初期化関数をインポートします。
  • from grongier.pex import Director: Flask アプリを IRIS 相互運用性フレームワークにバインドする Director クラスをインポートします。
  • import iris: IRIS ライブラリをインポートします。
  • app = Flask(__name__): Flask アプリケーションを作成します。
  • app.config['SQLALCHEMY_DATABASE_URI'] = 'iris+emb://IRISAPP': データベース URI を IRISAPP ネームスペースに設定します。
    • iris+emb URI スキームは、埋め込み接続として IRIS に接続するために使用されます(別の IRIS インスタンスの必要はありません)。
  • db = init_db(app): Flask アプリケーションでデータベースを初期化します。

models.py

このファイルには、アプリケーションの SQLAlchemy モデルが含まれます。

from dataclasses import dataclass
from typing import List
from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

@dataclass
class Comment(db.Model):
    id:int = db.Column(db.Integer, primary_key=True)
    content:str = db.Column(db.Text)
    post_id:int = db.Column(db.Integer, db.ForeignKey('post.id'))

@dataclass
class Post(db.Model):
    __allow_unmapped__ = True
    id:int = db.Column(db.Integer, primary_key=True)
    title:str = db.Column(db.String(100))
    content:str = db.Column(db.Text)
    comments:List[Comment] = db.relationship('Comment', backref='post')

説明することは特にありません。モデルはデータクラスとして定義されており、db.Model クラスのサブクラスです。

__allow_unmapped__ 属性は、comments 属性を使用せずに Post オブジェクトを作成できるようにするために使用する必要があります。

dataclasses はオブジェクトを JSON にシリアル化するのに使用されます。

init_db 関数は、Flask アプリケーションでデータベースを初期化します。

def init_db(app):
    db.init_app(app)

    with app.app_context():
        db.drop_all()
        db.create_all()
        # Create fake data
        post1 = Post(title='Post The First', content='Content for the first post')
        ...
        db.session.add(post1)
        ...
        db.session.commit()
    return db
  • db.init_app(app): Flask アプリケーションでデータベースを初期化します。
  • with app.app_context(): アプリケーションのコンテキストを作成します。
  • db.drop_all(): データベースのすべてのテーブルをドロップします。
  • db.create_all(): データベースのすべてのテーブルを作成します。
  • アプリケーションの偽データを作成します。
  • データベースオブジェクトを返します。

/iris エンドポイント

######################
# IRIS クエリ例 #
######################

@app.route('/iris', methods=['GET'])
def iris_query():
    query = "SELECT top 10 * FROM %Dictionary.ClassDefinition"
    rs = iris.sql.exec(query)
    # Convert the result to a list of dictionaries
    result = []
    for row in rs:
        result.append(row)
    return jsonify(result)

このエンドポイントは、IRIS データベースでクエリを実行し、IRISAPP ネームスペースに存在する上位 10 個のクラスを返します。

/interop エンドポイント

########################
# IRIS interop example #
########################
bs = Director.create_python_business_service('BS')

@app.route('/interop', methods=['GET', 'POST', 'PUT', 'DELETE'])
def interop():
    
    rsp = bs.on_process_input(request)

    return jsonify(rsp)

このエンドポイントは、IRIS の相互運用性フレームワークをテストするために使用されます。 ビジネスサービスオブジェクトを作成し、それを Flask アプリケーションにバインドします。

注: bs オブジェクトは有効な状態を維持するために、リクエストの範囲外にある必要があります。

  • bs = Director.create_python_business_service('BS'): 'BS' というビジネスサービスオブジェクトを作成します。
  • rsp = bs.on_process_input(request): リクエストオブジェクトを引数としてビジネスサービスオブジェクトの on_process_input メソッドを呼び出します。

/posts エンドポイント

############################
# CRUD operations posts    #
############################

@app.route('/posts', methods=['GET'])
def get_posts():
    posts = Post.query.all()
    return jsonify(posts)

@app.route('/posts', methods=['POST'])
def create_post():
    data = request.get_json()
    post = Post(title=data['title'], content=data['content'])
    db.session.add(post)
    db.session.commit()
    return jsonify(post)

@app.route('/posts/<int:id>', methods=['GET'])
def get_post(id):
    ...

このエンドポイントは、Post オブジェクトで CRUD 操作を実行するために使用されます。

dataclasses モジュールにより、Post オブジェクトは簡単に JSON にシリアル化できます。

以下では、すべての投稿を取得する sqlalchemy の query メソッドと、新しい投稿を作成するための addcommit メソッドを使用しています。

/comments エンドポイント

############################
# CRUD operations comments #
############################

@app.route('/comments', methods=['GET'])
def get_comments():
    comments = Comment.query.all()
    return jsonify(comments)

@app.route('/comments', methods=['POST'])
def create_comment():
    data = request.get_json()
    comment = Comment(content=data['content'], post_id=data['post_id'])
    db.session.add(comment)
    db.session.commit()
    return jsonify(comment)

@app.route('/comments/<int:id>', methods=['GET'])
def get_comment(id):
    ...

このエンドポイントは、Comment オブジェクトで CRUD 操作を実行するために使用されます。

Comment オブジェクトは外部キーによって Post オブジェクトにリンクされます。

トラブルシューティング

スタンドアロンモードで Flask アプリケーションを実行する方法

以下のコマンドを使用して、いつでもスタンドアロンの Flask アプリケーションを実行できます。

python3 /irisdev/app/community/app.py

注: このコマンドを実行するには、コンテナー内にいる必要があります。

docker exec -it iris-flask-template-iris-1 bash

IRIS でアプリケーションを再起動する

DEBUG モードでアプリケーションに複数の呼び出しを行うと、変更はアプリケーションに反映されます。

IRIS 管理ポータルへのアクセス方法

http://localhost:53795/csp/sys/UtilHome.csp に移動すると、IRIS 管理ポータルにアクセスできます。

このテンプレートをローカルで実行する

これには、マシンに IRIS がインストールされている必要があります。

次に、IRISAPP というネームスペースを作成する必要があります。

要件をインストールします。

IoP のインストール:

#init iop
iop --init

# load production
iop -m /irisdev/app/community/interop/settings.py

# start production
iop --start Python.Production

セキュリティポータルでアプリケーションを構成します。

0
0 69
記事 Toshihiko Minamoto · 2月 20, 2025 4m read

wsgi_logo

コンテキスト

ウェブサーバーゲートウェイインターフェース(WSGI)は、ウェブサーバーがリクエストを Python プログラミング言語で記述されたウェブアプリケーションまたはフレームワークに転送するための単純な呼び出し規則です。 WSGI は PEP 3333 で詳しく説明された Python 規格です。

🤔 定義は良いとして、IRIS との関連性は何でしょうか?

IRIS 2024.2+ の新機能により、直接 IRIS で WSGI アプリケーションを実行できます。 この機能は、IRIS を他の Python フレームワークとライブラリに統合する優れた方法です。

これは、Python を使用して IRIS と対話できる Python ファーストエクスペリエンスのトレンドに沿ったもので、Python アプリケーションを IRIS 上で直接実行することもできるようになりました。

使用方法

IRIS で WSGI アプリケーションをインスタンス化するには、IRIS 管理ポータルのセキュリティ -> アプリケーション -> ウェブアプリケーションのセクションで構成する必要があります。

単純な Flask の例:

/irisdev/app/community ディレクトリにある app.py というファイル:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

UI 構成

画像

このセクションでは、以下を指定することで WSGI アプリケーションを構成できます。

  • アプリケーション名

  • これは WSGI アプリケーションのファイル名に対応します

  • 例: app.py ですが、.py 拡張子を除きます : app

  • コーラブル名

    • WSGI サーバーによって呼び出されるコーラブル関数

    • 例: app は、app.py ファイルの app 変数に対応します

      • app = Flask(__name__)
  • WSGI アプリディレクトリ

    • WSGI アプリケーションが存在するパス
    • 例: /irisdev/app/community
  • Python プロトコルタイプ

    • wsgi またh asgi
      • wsgi はデフォルト値で、この例で使用されているタイプです
      • asgi は非同期アプリケーションに使用します
        • asgi は現時点では a2wsgi アダプターによって同期的にサポートされています
  • デバッグ

    • オンの場合、WSGI アプリケーションはデバッグモードで実行します
      • WSGI アプリケーションへの変更は自動的に再読み込みされるため、開発目的において便利です

CPF マージ

CPF を使用して WSGI アプリケーションを構成することも可能です。 構成の例を以下に示します。

[Actions]
CreateApplication:Name=/flask,NameSpace=IRISAPP,WSGIAppLocation=/irisdev/app/community/,WSGIAppName=app,WSGICallable=app,Type=2,DispatchClass=%SYS.Python.WSGI,MatchRoles=:%ALL,WSGIDebug=0,WSGIType=0

ログファイル

WSGI アプリケーションログは、インスタンスの mgr ディレクトリにある WSGI.log ファイルに保存されます。

以下は、IRIS で実行できる WSGI アプリケーションの例です。IRIS で様々な Python フレームワークを実行する方法を示すことを目的としています。

基本的に、ユースケースはすべてのフレームワークで同一です。

エンドポイント

  • /iris - IRISAPP ネームスペースに存在する上位 10 個のクラスを持つ JSON オブジェクトを返します。
  • /interop - IRIS の相互運用性フレームワークをテストするための ping エンドポイント。
  • /posts - Post オブジェクトの単純な CRUD エンドポイント。
  • /comments - Comment オブジェクトの単純な CRUD エンドポイント。

オブジェクトモデル

Post オブジェクト:

  • id
  • title
  • content

Comment オブジェクト:

  • id
  • post_id(Post の外部キー)
  • content

Flask

Django

FastAPI

制限

  • ASGI は現時点では a2wsgi アダプターによって同期的にサポートされています。
  • tornado アプリケーション(jupyter、streamlit など )は、WSGI に対応していないためサポートされていません。
0
0 59
記事 Mihoko Iijima · 1月 21, 2025 16m read

開発者の皆さん、こんにちは。

Teams ワークフロー Webhook を用意すると、curl コマンドや REST クライアントを利用して Teams チャネルに任意メッセージを簡単に送信できるので、IRIS や IRIS の Interoperability を使って自動的に何か情報を入手+必要なときだけ Teams チャネル通知ができたら面白いな、と思い試してみた内容をご紹介します。

以下、Teamsワークフローの作成例です。

Teams ワークフローの仕様に合わせたメッセージ用 JSON が用意できれば、こんなメッセージを出すことができます。

Teams チャネルにメッセージを通知するには「Teams ワークフローの Webhook」の用意が必要です。(この用意によってアクセスするために必要なURLが生成されます)詳しくは、「Microsoft Teamsのワークフローを使用して受信 Webhook を作成する」をご参照ください。

通知までの設定などについては、こちらのページを参考にさせていただきました:Teams チャネルへメッセージ送信する方法

以下、試した順でご紹介します。

1. curl コマンドでまずは実行してみる

2. シンプルにターミナルから試す

3. 通知メッセージのJSONを変えてみる

4. メッセージのJSONをJSONテンプレートエンジンで作ってみる

0
0 95