#Embedded Python

0 フォロワー · 75 投稿

Embedded Python は InterSystems IRIS カーネルへ Python プログラミング言語を組み込み、開発者が Python を使用してデータを処理し、サーバーサイドアプリケーションのビジネスロジックを開発できるようにするものです。

ドキュメントはこちらです

記事 Toshihiko Minamoto · 4月 1, 2024 5m read

大規模言語モデル(OpenAI の GPT-4 など)の発明と一般化によって、最近までは手動での処理が非現実的または不可能ですらあった大量の非構造化データを使用できる革新的なソリューションの波が押し寄せています。 データ検索(検索拡張生成に関する優れた紹介については、Don Woodlock の ML301 コースをご覧ください)、センチメント分析、完全自律型の AI エージェントなど、様々なアプリケーションが存在します。

この記事では、IRIS テーブルに挿入するレコードに自動的にキーワードを割り当てる単純なデータタグ付けアプリケーションの構築を通じて、IRIS の Embedded Python 機能を使って、Python OpenAI ライブラリに直接インターフェース接続する方法をご紹介します。 これらのキーワードをデータの検索と分類だけでなく、データ分析の目的に使用できるる単純なデータタグ付けアプリケーションを構築します。ユースケースの例として、製品の顧客レビューを使用します。

要件

  • IRIS の実行インスタンス
  • OpenAPI API キー(こちらで作成できます)
  • 構成済みの開発環境(この記事では VS Code を使用します)

Review クラス

顧客レビューのデータモデルを定義する ObjectScript クラスの作成から始めましょう。 簡潔さを維持するために、顧客の名前、製品名、レビュー本文、および生成するキーワードの 4 つの %String フィールドのみを定義します。 クラスはオブジェクトをディスクに保存できるように、%Persistent を拡張します。

Class DataTagging.Review Extends%Persistent
{
Property Name As%String(MAXLEN = 50) [ Required ];Property Product As%String(MAXLEN = 50) [ Required ];Property ReviewBody As%String(MAXLEN = 300) [ Required ];Property Keywords As%String(MAXLEN = 300) [ SqlComputed, SqlComputeOnChange = ReviewBody ];
}

ReviewBody への挿入または更新時に、Keywords プロパティが自動的に計算されるようにしたいため、これを SqlComputed とします。計算される値についての詳細は、こちらをご覧ください。

KeywordsComputation メソッド

次に、レビュー本文に基づいてキーワードを計算するために使用するメソッドを定義します。 公式の openai Python パッケージを直接操作するために、Embedded Python を使用できます。 ただし、先にそれをインストールしておく必要があります。 以下のシェルコマンドを実行しましょう。

<your-IRIS-installation-path>/bin/irispip install --target <your-IRIS-installation-path>/Mgr/python openai

OpenAI のチャット補完 API を使用して、キーワードを生成できるようになりました。

ClassMethod KeywordsComputation(cols As %Library.PropertyHelper) As %String [ Language = python ]
{
    '''
    This method is used to compute the value of the Keywords property
    by calling the OpenAI API to generate a list of keywords based on the review body.
    '''from openai import OpenAI
client = OpenAI(
    <span class="hljs-comment"># Defaults to os.environ.get("OPENAI_API_KEY")</span>
    api_key=<span class="hljs-string">"&lt;your-api-key&gt;"</span>,
)

<span class="hljs-comment"># Set the prompt; use few-shot learning to give examples of the desired output</span>
user_prompt = <span class="hljs-string">"Generate a list of keywords that summarize the content of a customer review of a product. "</span> \
            + <span class="hljs-string">"Output a JSON array of strings.\n\n"</span> \
            + <span class="hljs-string">"Excellent watch. I got the blue version and love the color. The battery life could've been better though.\n\nKeywords:\n"</span> \
            + <span class="hljs-string">"[\"Color\", \"Battery\"]\n\n"</span> \
            + <span class="hljs-string">"Ordered the shoes. The delivery was quick and the quality of the material is terrific!.\n\nKeywords:\n"</span> \
            + <span class="hljs-string">"[\"Delivery\", \"Quality\", \"Material\"]\n\n"</span> \
            + cols.getfield(<span class="hljs-string">"ReviewBody"</span>) + <span class="hljs-string">"\n\nKeywords:"</span>
<span class="hljs-comment"># Call the OpenAI API to generate the keywords</span>
chat_completion = client.chat.completions.create(
    model=<span class="hljs-string">"gpt-4"</span>,  <span class="hljs-comment"># Change this to use a different model</span>
    messages=[
        {
            <span class="hljs-string">"role"</span>: <span class="hljs-string">"user"</span>,
            <span class="hljs-string">"content"</span>: user_prompt
        }
    ],
    temperature=<span class="hljs-number">0.5</span>,  <span class="hljs-comment"># Controls how "creative" the model is</span>
    max_tokens=<span class="hljs-number">1024</span>,  <span class="hljs-comment"># Controls the maximum number of tokens to generate</span>
)

<span class="hljs-comment"># Return the array of keywords as a JSON string</span>
<span class="hljs-keyword">return</span> chat_completion.choices[<span class="hljs-number">0</span>].message.content

}

プロンプト内では、最初に「generate a list of keywords that summarize the content of a customer review of a product」で、製品の顧客レビューのコンテンツを要約するキーワードのリストを GPT-4 でどのように生成するかについての一般的な命令を指定してから、希望する出力と 2 つのサンプル入力を指定していることに注意してください。 次に cols.getfield("ReviewBody") を挿入し、「Keywords:」の語でプロンプトを終了することで、私が提示した例と同じ形式でキーワードを提供して、文を完成させるように促しています。 これは、Few-Shot プロンプティング手法の単純な例です。

この記事を簡潔にするため、キーワードを JSON 文字列で格納するようにしていますが、本番では、DynamicArray に格納するのがお勧めです。ただ、これについては各開発者にお任せします。

キーワードの生成

それでは、管理ポータルで以下の SQL クエリを使用してテーブルに行を挿入し、データタグ付けアプリケーションをテストしてみましょう。

INSERTINTO DataTagging.Review (Name, Product, ReviewBody)
VALUES ('Ivan', 'BMW 330i', 'Solid car overall. Had some engine problems but got everything fixed under the warranty.')

以下のとおり、4 つのキーワードが自動的に生成されました。 上出来です!

まとめ

まとめると、Python コードを埋め込む InterSystems IRIS の機能によって、非構造化データを処理する際に幅広い可能性を得られます。 OpenAI の力を活用して自動データタグ付けを行うのは、この強力な機能によって達成できることの一例にすぎません。 これにより、ヒューマンエラーを縮小し、全体的な効率をさらに高めることができます。

0
0 168
記事 Kosaku Ikeda · 10月 2, 2023 8m read

皆さまこんにちは。
IRIS for Healthを用いてFHIRの開発に携わっている者です。

FHIRリポジトリの導入を検討している方々に向けて、足がかり的な記事になればと思い投稿致します。

<アジェンダ>
■IISでの環境構築
■POSTMANを利用しないリソースへのデータアクセス
■Patientリソースの作成について
■FHIRリポジトリを使ってみての感想

■おまけEmbedded Pythonを使って、サンプルファイルからFHIRリソースへアクセスする方法

3
1 598
記事 Toshihiko Minamoto · 11月 15, 2023 9m read

前の記事 - AI による臨床文書の保管、取得、検索の単純化

この記事では、AI を使用した文字起こしと要約によってヘルスケアに変革を起こす OpenAI の高度な言語モデルの可能性を探ります。 OpenAPI の最先端 API を活用して、録音データを文字起こしし、自然言語処理アルゴリズムを使って簡潔な要約を生成するための重要なインサイトを抽出するプロセスを掘り下げていきます。

似たような機能は Amazon Medical Transcibe や Medvoice などの既存のソリューションでも提供されていますが、この記事では、OpenAI テクノロジーを使用してこれらの強力な機能を InterSystems FHIR に実装することに焦点を当てています。

Vue.js の録音データ

Vue.js アプリのボイスレコーダーは、完全にネイティブであり、Mediarecorder インターフェースを使って JavaScript で記述されています。 これは、アプリケーションを軽量に維持しながら、録音オプションを完全に制御できるようにすることを目的としています。 以下は、録音入力の開始と停止を行うスニペットです。

// オーディオストリームをチャンクとして保存する録音開始メソッドasync startRecording() {
      try {
        const stream = await navigator.mediaDevices.getUserMedia({
          audio: true,
        });
        this.mediaRecorder = new MediaRecorder(stream);
        this.mediaRecorder.start();

        this.mediaRecorder.ondataavailable = (event) => {
          this.chunks.push(event.data);
        };
        this.isRecording = true;
      } catch (error) {
        console.error("Error starting recording:", error);
      }
}

// 停止後にブロブを作成する(そして転写メソッドを呼び出す)録画停止メソッド
stopRecording() {
      if (this.mediaRecorder) {
        this.isLoading = true;
        this.mediaRecorder.stop();
        this.mediaRecorder.onstop = async () => {
          const blob = new Blob(this.chunks, {
            type: "audio/webm;codecs=opus",
          });
          awaitthis.sendAudioToWhisper(
            new File([blob], `file${Date.now()}.m4a`)
          );

          this.getSummary(this.transcription);
        };
      }
}

文字起こしコンポーネント

OpenAI の Whisper モデルを使った音声データの文字起こしには、いくつかの基本コンポーネントが使用されます。 以下のコードスニペットは、文字起こしプロセスに関わるステップを示します。

const apiKey = process.env.OPENAI_API_KEY;

const formData = new FormData();
formData.append("file", blob);
formData.append("model", "whisper-1");
formData.append("response_format", "json");
formData.append("temperature", "0");
formData.append("language", "en");

try {
  const response = await fetch(
    "https://api.openai.com/v1/audio/transcriptions",
    {
      method: "POST",
      headers: {
        Accept: "application/json",
        Authorization: `Bearer ${apiKey}`,
      },
      body: formData,
      redirect: "follow",
    }
  );

  const data = await response.json();
  if (data.text) {
    this.transcription = data.text;
  }
} catch (error) {
  console.error("Error sending audio to Whisper API:", error);
}

returnthis.transcription;
  1. API キー - OPENAI_API_KEY は、OpenAI API にアクセスするために必要な認証トークンです。
  2. フォームデータ - 文字起こしされる音声ファイルは、FormData オブジェクトに追加されます。 選択されたモデル(whisper-1)、レスポンス形式(json)、体温(``)、および言語(en)などの追加パラメーターも含まれています。
  3. API リクエスト - OpenAI API エンドポイント https://api.openai.com/v1/audio/transcriptions への POST リクエストには、ヘッダーとフォームデータを含むボディを指定して、fetch メソッドで送信されています。
  4. レスポンス処理 - API からのレスポンスがキャプチャされ、文字起こしされたテキストが data オブジェクトから抽出されます。 文字起こしを変数 this.transcription に割り当てて、さらに処理するか使用することができます。

要約コンポーネント

以下のコードスニペットは、OpenAI の text-davinci-003 モデルを使用したテキスト要約プロセスに関わる基本コンポーネントを示しています。

response = openai.Completion.create(
    model="text-davinci-003",
    prompt="Summarize the following text and give title and summary in json format. \
            Sample output - {\"title\": \"some-title\", \"summary\": \"some-summary\"}.\
            Input - "
    + text,
    temperature=1,
    max_tokens=300,
    top_p=1,
    frequency_penalty=0,
    presence_penalty=1
)

return response["choices"][0]["text"].replace('\n', '')
  1. モデルの選択 - model パラメーターは text-davinci-003 に設定されており、OpenAI のテキスト補完モデルが要約に使用されていることを示します。
  2. プロンプト - モデルに提供されるプロンプトは、望ましい結果を指定しています。これは入力テキストを要約して JSON 形式でタイトルと要約を返します。 入力テキストは、プロンプトに連結して処理されます。 OpenAI を通じてレスポンス変換を処理できるところに興味深いポイントがあります。 受信側での検証のみで十分であり、将来的にはコンバーターがほとんど必要なくなる可能性があります。
  3. 生成パラメーター - 生成された要約の動作と品質を制御するために、temperaturemax_tokenstop_pfrequency_penaltypresence_penalty などのパラメーターが設定されます。
  4. API リクエストとレスポンスの処理 - API リクエストを行うために、openai.Completion.create() メソッドが呼び出されます。 レスポンスがキャプチャされ、生成された要約テキストがレスポンスオブジェクトから抽出されます。 要約テキストに含まれる改行文字(\n)は、最終結果を返す前に取り除かれます。

FHIR のドキュメント参照

OpenAI テクノロジーを使用して医師と患者の会話の文字起こしと要約を実装する文脈においては、FHIR 規格内での診療記録の保管を考慮することが重要です。 FHIR は、診療記録などの医療情報を様々な医療システムやアプリケーション間で交換するための構造化された標準アプローチです。 FHIR の DocumentReference リソースは、診療記録や関連文書を保管するための専用のセクションとして機能します。

文字起こしと要約機能を医師と患者の会話ワークフローに統合する場合、生成される文字起こしと要約は、FHIR Documents リソース内の診療記録として保管できます。 これにより、生成されたインサイトへのアクセス、取得、およびヘルスケアプロバイダーやその他の承認機関の間での共有を簡単に行えます。

{
    "resourceType": "Bundle",
    "id": "1a3a6eac-182e-11ee-9901-0242ac170002",
    "type": "searchset",
    "timestamp": "2023-07-01T16:34:36Z",
    "total": 1,
    "link": [
        {
            "relation": "self",
            "url": "http://localhost:52773/fhir/r4/Patient/1/DocumentReference"
        }
    ],
    "entry": [
        {
            "fullUrl": "http://localhost:52773/fhir/r4/DocumentReference/1921",
            "resource": {
                "resourceType": "DocumentReference",
                "author": [
                    {
                        "reference": "Practitioner/3"
                    }
                ],
                "subject": {
                    "reference": "Patient/1"
                },
                "status": "current",
                "content": [
                    {
                        "attachment": {
                            "contentType": "application/json",
                            "data": ""
                        }
                    }
                ],
                "id": "1921",
                "meta": {
                    "lastUpdated": "2023-07-01T16:34:33Z",
                    "versionId": "1"
                }
            },
            "search": {
                "mode": "match"
            }
        }
    ]
}

試してみましょう

  1. プロジェクトをクローン - 次の GitHub リンクからプロジェクトリポジトリをクローンします: https://github.com/ikram-shah/iris-fhir-transcribe-summarize-export
  2. ローカルでセットアップ - 提供された指示に従って、プロジェクトをローカルマシン上にセットアップします。 セットアップ中に問題が発生した場合は、お知らせください。
  3. 患者を選択 - プロジェクト内の提供されたサンプルリストから患者を選択します。 この患者は、文字起こしと要約に使用される医師と患者の会話と関連付けられます。
  4. 対話ページ - 患者が選択されたら、プロジェクト内の対話ページに移動します。 このページで、「Take Notes」オプションを見つけてクリックし、医師と患者の会話の文字起こしプロセスを開始します。
  5. 文字起こしの表示と編集 - 文字起こしプロセスが完了したら、生成された文字起こしを表示するオプションが表示されます。 さらに整理してわかりやすくするために、文字起こしに関連付けられたタイトルと要約を編集することもできます。
  6. FHIR DocumentReference に保存 - タイトルと要約の処理が完了し、変更を保存すると、FHIR DocumentReference 内に自動的に保管されます。 これにより、関連する診療記録がキャプチャされ、それぞれの患者の記録に確実に関連付けられます。 現時点では、このプロジェクトは文字起こしテキスト全体を保存しませんが、 完全な文字起こしの補完を含めるように変更することもできます。

デモ

アプリケーション全体のデモはこちらでご覧ください: https://youtu.be/3Th6bR4rw0w

今後の方向性

AI を活用した文字起こしと要約の応用を遠隔医療通信に拡大することには、計り知れない可能性が秘められています。 これらの機能を Zoom、Teams、Google Meet などの一般的な会議プラットフォームに統合することで、医師と患者のリモート対話を合理化できる可能性があります。 遠隔医療セッションの自動文字起こしと要約機能には、正確な文書作成や分析の強化といったメリットがあります。 ただし、データプライバシーが重大な課題として残されます。 これに対応するためには、外部サーバーにデータを送信する前に、個人を特定できる情報(PII)をフィルターまたは匿名化する対策を実装する必要があります。

今後の方向性としては、ローカルで処理するためのオンデバイス AI モデルの調査、多言語コミュニケーションのサポートの改善、プライバシー維持した手法の進歩が挙げられます。

有用な実装だと思われた方は、Grand Prix 2023 でこのアプリに投票してください。

0
1 337
記事 Junichi Sakata · 11月 6, 2023 6m read

Python流行ってますよね。(一時は圧倒的な支配力のあったJavaも、O社に買われてライセンスが云々とか言われ始めた頃からブレーキが掛かってしまった気がします。)

Pythonの魅力の一つがパッケージで様々な機能が提供されていることがあげられるかなと思っています。

私もこれまでPythonのコードをそこそこ書いてきました。実のところ、ここ1年では間違いなくObject ScriptよりPythonのほうが書いた量が多いです。Excelのドキュメントがそれらよりも遥かに多いのは何とかしたいところですが😅

IRISと連携するため$ZF(-1)を使ってPythonプログラムをコールしているものもあります。

IRIS 2021.2からPythonがIRISにEmbedded Pythonとして組み込まれたということで、どのように使えるかを試してみました。

なお、使用した環境は以下です。

0
0 760
記事 Toshihiko Minamoto · 10月 26, 2023 4m read

問題

あわただしい臨床環境では迅速な意思決定が重要であるため、文書保管とシステムへのアクセスが合理化されていなければいくつもの障害を生み出します。 文書の保管ソリューションは存在しますが(FHIR など)、それらの文書内で特定の患者データに有意にアクセスして効果的に検索するのは、重大な課題となる可能性があります。

動機

AI により、文書の検索が非常に強力になりました。 ChromaLangchain のようなオープンソースツールを使用して、ベクトル埋め込みを保存して使用し、生成 AI API 全体でクエリを実行することで、ドキュメント上での質疑応答がかつてないほど簡単になっています。 より献身的に取り組む組織は、既存のドキュメントにインデックスを作成し、エンタープライズ用に微調整されたバージョンの GPT を構築しています。 GPT の現状に関する Andrej Karpathy の講演では、このトピックに関する素晴らしい概要が提供されています。

このプロジェクトは、医療関係者が文書を操作するあらゆるタッチポイントにおいて発生する摩擦を緩和する試みです。 医療関係者が情報を保管し、必要な情報を難なく検索できるように、入力と処理から保管と検索まで、IRIS FHIR と AI を活用しました。

ソリューション

医療関係者が音声メモを記録できるフルスタックのウェブアプリを構築しました。 これらのメモは、Open AI を使って文字起こしされ、要約されてから FHIR サーバーに保管されます。 保管されたドキュメントは、インデックス作成されてから、セマンティック検索で使用できるようになります。  

デモ動画

主な機能

  1. ウェブアプリ - 患者、観察、遭遇に関する診療情報を表示します。 これは Vue.js で構築されています。
  2. 音声データの文字起こし - Open AI Whisper API を使って、録音を正確なテキストに文字起こしします。
  3. テキストの要約 - 文字起こしされた内容を必要なフォーマットで要約してタイトルが付けられます。 症状、診断などの具体的なセクションなどです。 これは、text-da-vinci-003 を使った Open AI テキスト補完 API で行われます。
  4. ドキュメントの保管 - 要約されたドキュメントは、DocumentReference アーティファクトを使って FHIR に保管されます。
  5. セマンティックドキュメント検索 - 保管されたドキュメントはインデックス作成されて、チャンクとして Chroma に保管されます。 これは、Langchain を使用して検索スペースを制限してセマンティック検索に GPT トークンを控えめに使用するために使用されます。 現時点では、使用できるドキュメント数が少ないため、検索時にドキュメントを読み込んでいますが、 非同期的にバックグラウンドでインデックス作成するように変更することが可能です。
  6. ドキュメントのエクスポート - 最後に、ドキュメントを Google Docs に、その他のデータを Google Sheets にエクスポートするオプションがあります。 ユーザーは他の医療関係者や患者とのコラボレーションとやり取りを簡単に行えるように、OAuth を使って特定のアカウントにログインし、ドキュメントをエクスポートすることができます。

試してみましょう

次の GitHub リンクからプロジェクトリポジトリをクローンします: https://github.com/ikram-shah/iris-fhir-transcribe-summarize-export。 提供された指示に従って、プロジェクトをローカルマシン上にセットアップしてください。 期待される動作が得られない場合は、お知らせください。

ご意見とフィードバック

現在使用できる高度言語モデルと大量のデータを合わせることで、ヘルスケア分野の特に文書管理の領域に革命を起こす大きな可能性があります。 以下に、ご意見やフィードバックをお寄せください。 このプロジェクトの背後にある技術的な情報について、さらに多くの記事を投稿する予定です。

このプロジェクトに期待できると思われる場合は、Grand Prix コンテストでこのアプリに投票してください!

0
0 184
お知らせ Mihoko Iijima · 8月 29, 2023

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

InterSystems Python プログラミングコンテスト 2023 のテクノロジーボーナス詳細が決定しました!

  • Embedded Python - 3
  • Python Native API  - 3
  • Python Pex Interoperability - 4
  • Python libs: sqlalchemy and dbt - 2
  • LLM AI or LangChain usage: Chat GPT, Bard and others - 4
  • NoObjectScriptLine - 5
  • Questionnaire - 2
  • Docker コンテナの利用 - 2 
  • ZPM Package によるデプロイ - 2
  • オンラインデモ - 2
  • コミュニティ(USコミュニティ)に記事を投稿する(最初の記事) - 2
  • コミュニティ(USコミュニティ)に2つ目の記事を投稿する - 1
  • YouTubeにビデオを公開 - 3

詳細は以下の通りです。<--break->

<--break->Embedded Python - 3 ポイント

応募されるアプリケーションに Embedded Python を使用している場合、4ポイント獲得できます。Embedded Python を利用する場合は、IRIS 2021.2以降のバージョンをご利用ください。

0
0 98
お知らせ Mihoko Iijima · 8月 8, 2023

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

次の InterSystems オンラインプログラミングコンテストは、Pythonに特化した内容を予定しています!

🏆 InterSystems Python プログラミングコンテスト 🏆

期間: 2023年9月4日~24日

賞金総額: $13,500


0
0 402
記事 Toshihiko Minamoto · 7月 24, 2023 8m read

Python は世界で最も使用されているプログラミング言語になり(出典: https://www.tiobe.com/tiobe-index/)、SQL はデータベース言語としての道をリードし続けています。 Python と SQL が連携して、SQL だけでは不可能であった新しい機能を提供できれば、素晴らしいと思いませんか? 結局のところ、Python には 380,000 を超える公開ライブラリがあり(出典: https://pypi.org/)、Python 内で SQL クエリを拡張できる興味深い機能が提供されています。 この記事では、Embedded Python を使用して、InterSystems IRIS データベースに新しい SQL ストアドプロシージャを作成する方法を詳しく説明します。

サンプルとして使用する Python ライブラリ

この記事では、IRIS で SQL を扱う人にとって非常に便利な GeoPy と Chronyk という 2 つのライブラリを使用します。 

Geopy は、ジオコーディング(住所と地理座標の修飾)を住所データに適用するために使用するライブラリです。 これを使用すると、通りの名前から郵便番号と完全な住所を郵便局の形式で取得することができます。 多くのレコードには住所が含まれるため、非常に便利です。

Chronyk は、人間の言語で日付と時刻を処理するために使用されます。 これは、IRIS と Python の両方において、日付は内部的に最初の日付から経過した時間を表す数字でたるため、非常に便利です。 人間の場合、日付は 7 月 20 日、または昨日や明日、または 2 時間前と表現しますが、 Chronyk では、このような日付を受け取って、ユニバーサル日付形式に変換します。

InterSystems IRIS への Python サポート

バージョン 2021.1 より、Python を使用してクラスメソッド、ストアドプロシージャ、相互運用プロダクション、Python と IRIS(ObjectScript)間の双方向のネイティブ呼び出しを作成できるようになりました。 Python とこれほど深く連携するデータプラットフォームを他に知りません。 これが機能するためには、要件として、Python が IRIS と同じ同じ物理マシンか仮想マシンまたはコンテナにインストールされている必要があります。 詳細は、https://docs.intersystems.com/iris20221/csp/docbook/DocBook.UI.Page.cls?KEY=AFL_epython をご覧ください。 Python をインストールするには、以下を実行します。

# install libraries required for python and pip
RUNapt-get-yupdate\
    &&apt-get-yinstallapt-utils\
    &&apt-getinstall-ybuild-essentialunzippkg-configwget\
    &&apt-getinstall-ypython3-pip  

InterSystems IRIS への Python ライブラリサポート

InterSystems IRIS が Python ライブラリを使用できるようにするには、Python ライブラリが <installdir>/mgr/python にインストールされている必要があります。 installdir は IRIS がインストールされているフォルダです。 新しいパッケージをインストールするには、以下を実行します。

# use pip3 (the python zpm) to install geopy and chronyk packages
RUNpip3install--upgradepipsetuptoolswheel
RUNpip3install--target/usr/irissys/mgr/pythongeopychronyk

Pip3 は Python の最も一般的なパッケージマネージャーおよびインストーラー Pip です。

Python 言語でストアドプロシージャを作成する

InterSystems IRIS で Python を使用する可能性の 1 つは、Python を使用してストアドプロシージャを作成することです。 以下の 2 つの可能性があります。

  1. Create 関数またはプロシージャの SQL 文を使用したストアドプロシージャ Python の作成。
  2. sqlProc タグと language=Python タグを使用した ObjectScript クラス内での ClassMethod の作成。

Create プロシージャの SQL 文を使用したストアドプロシージャ Python の作成

InterSystems ドキュメントによると、以下に示すとおり、CREATE ステートメントに LANGUAGE PYTHON 引数を指定することで、Embedded Python を使って SQL 関数またはストアドプロシージャを記述することもできます(出典: https://docs.intersystems.com/iris20221/csp/docbook/DocBook.UI.Page.cls?KEY=AEPYTHON#AEPYTHON_runpython_sql)。

CREATE FUNCTION tzconvert(dt TIMESTAMP, tzfrom VARCHAR, tzto VARCHAR)
    RETURNS TIMESTAMP
    LANGUAGE PYTHON
{
    from datetime import datetime
    from dateutil import parser, tz
    d = parser.parse(dt)
    if (tzfrom is not None):
        tzf = tz.gettz(tzfrom)
        d = d.replace(tzinfo = tzf)
    return d.astimezone(tz.gettz(tzto)).strftime("%Y-%m-%d %H:%M:%S")
}

この新しい SQL 関数を実行する場合:

SELECT tzconvert(now(), 'US/Eastern', 'UTC')

関数は以下のようなものを返します。

2022-07-20 15:10:05

sqlProc タグと language=Python タグを使用した ObjectScript クラス内での ClassMethod の作成

正直に言うと、sqlProc タグと language=Python タグを使って ClassMethod を作成するこのアプローチが私のお気に入りです。 私の意見では、管理しやすく、十分な文書化で明確に示されており、ソースコードバージョンの管理もうまく行えます。 このアプローチのためのサンプルアプリケーションを公開しました(https://openexchange.intersystems.com/package/Python-IRIS-SQL-Procedures-Sample)。 これを使用して、この 2 番目のアプローチを詳しく説明します。

サンプルアプリケーションのインストール

サンプルアプリケーションをインストールするには、以下の手順に従います。

  1. リポジトリを任意のローカルディレクトリに Clone/git pull します。
$ git clone https://github.com/yurimarx/iris-sql-python-sample.git
  1. このディレクトリで Docker ターミナルを開き、以下を実行します。
$ docker-compose build
  1. IRIS コンテナを実行します。
$ docker-compose up -d

もう 1 つのインストール方法は、ZPM を使用する方法です。

zpm "install iris-sql-python-sample"

Python を使用したストアドプロシージャのサンプル

最初の例は、住所のジオコーディングを処理するストアドプロシージャです。ソースコードを参照してください。

ClassMethodGetFullAddress(StreetAs%String,CityAs%String,StateAs%String)
  <div>
    <span style="color: #85a6ff;">As</span><span style="color: #d4d4d4;"> </span><span style="color: #4ec9b0;">%String</span><span style="color: #d4d4d4;"> </span><span style="color: #ffffff;">[</span><span style="color: #d4d4d4;"> </span><span style="color: #85a6ff;">Language</span><span style="color: #d4d4d4;"> </span><span style="color: #ffffff;">=</span><span style="color: #d4d4d4;"> </span><span style="color: #d4b57c;">python</span><span style="color: #ffffff;">,</span><span style="color: #d4d4d4;"> </span><span style="color: #85a6ff;">SqlName</span><span style="color: #d4d4d4;"> </span><span style="color: #ffffff;">=</span><span style="color: #d4d4d4;"> </span><span style="color: #dcdcaa;">GetFullAddress</span><span style="color: #ffffff;">,</span><span style="color: #d4d4d4;"> </span><span style="color: #85a6ff;">SqlProc</span><span style="color: #d4d4d4;"> </span><span style="color: #ffffff;">]</span>
  </div>
  
  <div>
    <span style="color: #ffffff;">{</span>
  </div>
  
  <div>
    <span style="color: #85a6ff;">    </span><span style="color: #85a6ff;">import</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">geopy</span><span style="color: #ffffff;">.</span><span style="color: #ade2ff;">geocoders</span>
  </div>
  
  <div>
    <span style="color: #85a6ff;">    </span><span style="color: #85a6ff;">from</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">geopy</span><span style="color: #ffffff;">.</span><span style="color: #ade2ff;">geocoders</span><span style="color: #85a6ff;"> </span><span style="color: #85a6ff;">import</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">Nominatim</span>
  </div>
  
  <div>
    <span style="color: #ade2ff;">    </span><span style="color: #ade2ff;">geopy</span><span style="color: #ffffff;">.</span><span style="color: #ade2ff;">geocoders</span><span style="color: #ffffff;">.</span><span style="color: #ade2ff;">options</span><span style="color: #ffffff;">.</span><span style="color: #ade2ff;">default</span><span style="color: #ade2ff;">_</span><span style="color: #ade2ff;">timeout</span><span style="color: #ffffff;"> =</span><span style="color: #d4b57c;"> </span><span style="color: #d4b57c;">7</span>
  </div>
  
  <div>
    <span style="color: #ade2ff;">    </span><span style="color: #ade2ff;">geolocator</span><span style="color: #ffffff;"> =</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">Nominatim</span><span style="color: #ffffff;">(</span><span style="color: #ade2ff;">user</span><span style="color: #ade2ff;">_</span><span style="color: #ade2ff;">agent</span><span style="color: #ffffff;">=</span><span style="color: #d4b57c;">"intersystems_iris"</span><span style="color: #ffffff;">)</span>
  </div>
  
  <div>
    <span style="color: #ade2ff;">    </span><span style="color: #ade2ff;">location</span><span style="color: #ffffff;"> =</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">geolocator</span><span style="color: #ffffff;">.</span><span style="color: #ade2ff;">geocode</span><span style="color: #ffffff;">(</span><span style="color: #ade2ff;">Street</span><span style="color: #ffffff;"> +</span><span style="color: #d4b57c;"> </span><span style="color: #d4b57c;">", "</span><span style="color: #ffffff;"> +</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">City</span><span style="color: #ffffff;"> +</span><span style="color: #d4b57c;"> </span><span style="color: #d4b57c;">", "</span><span style="color: #ffffff;"> +</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">State</span><span style="color: #ffffff;">,</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">country</span><span style="color: #ade2ff;">_</span><span style="color: #ade2ff;">codes</span><span style="color: #ffffff;">=</span><span style="color: #d4b57c;">"US"</span><span style="color: #ffffff;">)</span>
  </div>
  
  <div>
    <span style="color: #85a6ff;">    </span><span style="color: #85a6ff;">return</span><span style="color: #ade2ff;"> </span><span style="color: #ade2ff;">location</span><span style="color: #ffffff;">.</span><span style="color: #ade2ff;">address</span>
  </div>
  
  <div>
    <span style="color: #ffffff;">}</span>
  </div>
</div>

ClassMethod が [ Language = python, SqlProc] タグで(dc.pythonsql.Company クラス内に)宣言されているのが分かります。
SqlName タグによって、新しいストアドプロシージャの名前を SQL 分に設定できます。

管理ポータルの[システム]>[SQL]に移動し、以下のコードを実行します。

SELECT 
ID, City, Name, State, Street, Zip, dc_pythonsql.GetFullAddress(Street, City, State) As FullAddress 
FROM dc_pythonsql.Company

結果が表示されます。

Geopy

不完全な住所から「完全な」住所(完全修飾)が返されるようになりました。

注意: 何も返されない場合は、#class(dc.pythonsql.Company).CreateFiveCompanies() を実行してください。 テストに使用する 5 つの会社が作成されます。

このパッケージは、主なオープンのジオコーディングサービスと有料のサービスと連携できます。 この例では、Nominatim というオープンサービスを使用していますか、Bing、Google、ArcGIS などを使用することも可能です。 利用可能なサービスについて、https://geopy.readthedocs.io/en/stable/#module-geopy.geocoders をご覧ください。

2 つ目の例は、人間が読み取れる形式による Chronyk という日付と時刻のパッケージです。

「明日」、「昨日」、「今から 4 時間後」、「2022 年 7 月 4 日」などの文を送信し、ユニバーサル日付形式の結果を取得できます。 ストアドプロシージャの作成を参照してください。

ClassMethodGetHumanDate(SentenceAs%String)As%String[Language=python,SqlName=GetHumanDate,SqlProc]
{
    fromchronykimportChronyk
    t =Chronyk(Sentence)
    returnt.ctime()
}

管理ポータル >[システム]>[SQL]で、以下の呼び出しを実行します。

SELECT 
ID, City, Name, State, Street, Zip, dc_pythonsql.GetHumanDate('yesterday') As Datetime      
FROM dc_pythonsql.Company

結果が表示されます。

https://raw.githubusercontent.com/yurimarx/iris-sql-python-sample/main/screen2.png

ストアドプロシージャを呼び出すだけの場合は、この SQL 分を使用できます。

select dc_pythonsql.GetHumanDate('yesterday') as Datetime  

このライブラリには、人間が読み取れる日付と時刻の例が複数含まれています。https://github.com/KoffeinFlummi/Chronyk をご覧ください。

Python ストアドプロシージャは簡単に作成できます。ぜひ試してみてください!

0
0 399
記事 Nobuyuki Hata · 7月 10, 2023 1m read

最近人気上昇中のプログラミング言語Python、ご存じのとおりIRISでは2通りの使い方が出来ます。

組み込みPython(Embedded Python)

PythonコードはIRISプロセス内でObjectScriptコードと並列に実行

具体的には

  1. IRISクラス内のメソッド
  2. SQL関数とストアドプロシージャ
  3. ターミナルからPythonシェルを起動
  4. irispythonコマンド実行

が該当します。

ネイティブAPI(Native API)

IRISの外からグローバルへのアクセス、クラスメソッドを呼び出し

上の4種類以外は全てネイティブAPIを使用します。

Pythonコードが実行される場所でIRISへのアクセス手段が決まりますが、ライブラリ名が双方とも”iris”のため注意が必要です。

* 従来からのirisnativeはDeprecated(非推奨)となりました

サンプルコードを探す時やドキュメントを参照する時、どちらのPython APIを使用しているか頭の片隅にあると予期せぬエラーに遭遇する機会が減るかも知れません。

組み込みPythonのirisパッケージ

 

組み込み Python | InterSystems IRIS Data Platform 2022.1
 

ネイティブSDKのirisパッケージ

0
0 381
記事 Toshihiko Minamoto · 7月 5, 2023 39m read

この記事では、InterSystems IRIS の学習に関連したトピックについて、開発者コミュニティでの厳選された記事にアクセスすることができます。機械学習や Embedded Python、JSON、API と REST アプリ、InterSystems環境の構築と管理、DockerとCloud、VSCode、SQL、Analytics/BI、グローバル、セキュリティ、DevOps、インターオペラビリティNative API、それぞれでランク付けされたトップの記事を見ることができます。ぜひ、楽しみながら学んでください!  

機械学習

機械学習は、高度なデータ分析を構築し、優れた効率で手動活動を自動化するための必須技術です。既存のデータから学習する認知モデルを作成し、自己調整されたアルゴリズムに基づいて予測、確率計算、分類、識別、「非創造的」な人間の活動の自動化を実行します。

すべてのシナリオにおいて、InterSystems IRISは、これらのマシンラーニングモデルを作成、実行、利用可能にし、使用するためのデータプラットフォームおよび環境として機能します。IRISは、SQLコマンドからのML利用(IntegratedML)、Embedded PythonやPMML(Predictive Model Markup Language)による機械学習が可能です。以下の記事でその機能を確認することができます。

名称概要URL
IntegratedMLハンズオンラボIntegratedMLの実践的な概要https://community.intersystems.com/post/integratedml-hands-lab
InterSystems IRISデータプラットフォームによるAIロボット化IRISプロダクションのAIhttps://community.intersystems.com/post/ai-robotization-intersystems-iris-data-platform
IRIS IntegratedMLを使った糖尿病予測WebアプリIntegratedMLサンプルhttps://jp.community.intersystems.com/node/535221
妊産婦の健康リスクの予測IntegratedMLサンプルhttps://community.intersystems.com/post/predict-maternal-health-risks
機械学習によるコミュニティー記事の整理 - 1Python MLライブラリの利用https://community.intersystems.com/post/using-machine-learning-organize-community-1

 

ObjectScript言語

ObjectScript は InterSystems のオフィシャルプログラミング言語です。簡単で柔軟性があり、バックエンド、統合、および分析アプリケーションの作成に非常に強力です。詳細については、以下の記事を参照してください。

名称概要URL
InterSystems ObjectScript 101++ (EN)ObjectScriptを学ぶビデオシリーズhttps://community.intersystems.com/post/intersystems-objectscript-101-en
$Sequence関数について数列の作成するhttps://community.intersystems.com/post/sequence-function
Caché ObjectScript でのパフォーマンスの高いループの作成ループの作成https://jp.community.intersystems.com/node/481811
データの匿名化、iris-Disguiseの導入ObjectScript の永続的なクラスとプロパティをカスタマイズする方法について説明するhttps://jp.community.intersystems.com/node/510731
ObjectScriptのエラー処理に関するスニペット例外処理https://jp.community.intersystems.com/node/491451
ObjectScriptにおける従来のデバッグデバッグ手法https://community.intersystems.com/post/traditional-debugging-objectscript
Caché での正規表現の使用正規表現を使った作業https://jp.community.intersystems.com/node/481816
ObjectScript における堅牢なエラー処理とクリーンアップ品質の高いコードを書くhttps://jp.community.intersystems.com/node/486226
InterSystems Ensembleを愛し、心配することをやめた理由プロダクションでのJSON処理https://community.intersystems.com/post/how-we-learned-stop-worrying-and-love-intersystems-ensemble
より使いやすくなったオブジェクト・ダンプダンプするオブジェクトhttps://community.intersystems.com/post/more-usefull-object-dump
InterSystems IRISのマクロを使ったロギングマクロを使ったロギングhttps://jp.community.intersystems.com/node/503796
SYSLOG - その実態と意味することシスログのデバッグ情報https://jp.community.intersystems.com/node/492146
%Statusを使ったデバッグのヒント%Statusを使ったデバッグhttps://jp.community.intersystems.com/node/503801
$Queryの有効活用$Query を使ってデータを探すhttps://community.intersystems.com/post/making-most-query
多次元プロパティの永続性 - Part 1 (クラシック)多次元永続プロパティhttps://community.intersystems.com/post/multidimensional-property-persistence-part-1-classic
採用されたBitmapBitmap インデックスhttps://community.intersystems.com/post/adopted-bitmap
タイムロードになる方法 - 誕生日付と時刻のAPIhttps://jp.community.intersystems.com/node/527796
正確なバージョン情報($zv / $zversion)の重要性と収集についてIRISバージョン取得https://community.intersystems.com/post/importance-and-collection-exact-version-information-zv-zversion
1840年12月以前の日付 ? $H( orolog )がネガティブ?ネガティブな日付https://community.intersystems.com/post/date-dec1840-negative-horolog
Caché でのカスタム・インデックス・タイプの作成カスタムインデックスの作成https://jp.community.intersystems.com/node/479316
$LIST 文字列フォーマットと %DynamicArray および %DynamicObject クラス$LIST、%DynamicObject、%DynamicArrayの使用法https://jp.community.intersystems.com/node/483711
^ERRORグローバルに対するSQLSQLを使ってエラーの内容の確認https://community.intersystems.com/post/sql-error-global
コードによるデフォルト設定値の追加デフォルト値の設定https://community.intersystems.com/post/add-default-setting-value-code
ダイナミックオブジェクトの反復処理イテレート(反復処理)の使用https://community.intersystems.com/post/iterate-over-dynamic-object
クラスのすべてのプロパティをリストアップする (ObjectScriptがお気に入りな理由)ObjectScriptプロパティの反復使用https://jp.community.intersystems.com/node/515786
いつも使っているtry catchブロックTry Catchのハンドリングhttps://community.intersystems.com/post/try-catch-block-i-usually-use-intersystems-objectscript
ObjectScriptでシェルコマンドの実行ObjectScriptでシェルコマンドの実行https://community.intersystems.com/post/running-shell-commands-objectscript

Embedded Python

Python は、世界で最も人気があり、よく使われているプログラミング言語の 1 つです (https://www.tiobe.com/tiobe-index/)。InterSystems IRIS は、すべての主要なプログラミング言語に対して開かれたデータ・プラットフォームです。しかし、Python は、この素晴らしい言語とそのライブラリは、クラス、SQL、および統合/プロダクショ ンなど、IRIS のあらゆる場所で使用することができます。ObjectScript ( InterSystems のプログラミング言語 ) を知らない、または知りたくない人にとって、Python は素晴らしい選択肢となります。そのやり方については、以下の記事を参照してください。

名称概要URL
機械と戦おうEmbedded Pythonを使ったチックタックトー・ゲームの構築https://community.intersystems.com/post/lets-fight-against-machines
InterSystems IRIS 2021.2+ Python サンプル ( Embedded, Native API およびノートPC)複数のPythonノートPCでPythonとIRISを見るhttps://community.intersystems.com/post/intersystems-iris-20212-python-examples-embedded-native-apis-and-notebooks
Embedded PythonによるWebSocketクライアントCustom Socket サンプルhttps://community.intersystems.com/post/websocket-client-embedded-python
AWS LambdaにおけるIRIS Python Native APIAWSでのPythonhttps://community.intersystems.com/node/485361
JupyterノートPCにObjectScriptを追加する方法ノートPCでのIRIShttps://jp.community.intersystems.com/node/521496
ようこそDjangoIRISをデータベースとしたPython Djangoアプリの作成https://jp.community.intersystems.com/node/527801
IRISとGoogle Maps APIによるジオコーディングGeocoding python ライブラリの使用https://community.intersystems.com/post/geocoding-iris-and-google-maps-api
IRISとPython gTTSを用いたテキストから音声への変換のためのRESTサービスgTTSを使用したPythonサンプルhttps://community.intersystems.com/post/rest-service-convert-text-audio-using-iris-and-python-gtts
Python Flask WebフレームワークによるIRISレスポンシブダッシュボードの作成IRISによるFlask Webアプリhttps://community.intersystems.com/post/building-iris-responsive-dashboard-python-flask-web-framework

JSON

JSON は、マーケットで最も広く使用されている、データの送受信のための相互運用性フォーマットの 1 つです。InterSystems IRIS は、いくつかの方法でこの形式をサポートしています。JSON (DocDB) でネイティブ・データベースを持ち、オブジェクトを直列化および非直列化し、特に REST サービスからの要求と応答を JSON で処理することが可能です。以下の記事を確認してください。

名称概要URL
Caché 2016.1における新しいJSON機能の紹介ObjectScript JSON API の紹介https://community.intersystems.com/post/introducing-new-json-capabilities-cach%C3%A9-20161
JSONの機能強化JSON Adaptor APIhttps://jp.community.intersystems.com/node/481776

APIとRESTアプリ

バックグラウンドアプリケーションは現在、REST(Representational State Transfer)パラダイムで開発され、Web APIとして公開されています。以下の記事で、その仕組みを確認してください。

名称概要URL
InterSystemsのデータプラットフォームのためのGraphQLGraphQLスタイルでREST APIの作成https://jp.community.intersystems.com/node/481796
InterSystems API Managerの紹介API Managementの概要https://community.intersystems.com/post/introducing-intersystems-api-manager
RESTの高度なURLマッピングAPIへの経路のマッピングhttps://jp.community.intersystems.com/node/497976
AppS.REST: InterSystems IRISのための新しいRESTフレームワークRESTアプリを簡単に作成https://jp.community.intersystems.com/node/497991
RESTForms : クラスのためのREST APICRUDアプリケーションのためのREST APIの開発https://jp.community.intersystems.com/node/479226
スペックファーストのアプローチによるREST APIの作成Contract First ApproachによるAPI開発https://jp.community.intersystems.com/node/476556
ObjectScript REST API クックブックREST API 開発のヒントhttps://community.intersystems.com/post/objectscript-rest-api-cookbook
永続クラスとシリアルクラスからSwaggerスペックを生成するContract First ApproachによるAPI開発https://jp.community.intersystems.com/node/490976
InterSystems IRIS REST アプリケーションのパターンIRISによるAPI RESTの作成https://community.intersystems.com/post/intersystems-iris-rest-application-patterns
SUSHIでFHIRプロファイルを作成しよう 第1回カスタムFHIRプロファイルの作成https://jp.community.intersystems.com/node/493351
ゼロから使いこなすIAMIAMでAPIの管理https://jp.community.intersystems.com/node/493416
InterSystems API Management を使用してAPIの負荷を分散するAPIMによるAPIのロードバランスhttps://jp.community.intersystems.com/node/482711
InterSystems API Management で OAuth 2.0 による API のセキュリティの確保 - 第1回APIMによるAPI のセキュリティの確保hhttps://jp.community.intersystems.com/node/497946
InterSystems IRISアプリケーションのAngular UIを5分で取得IRISとAngularによるFull Stackアプリhttps://community.intersystems.com/post/getting-angular-ui-your-intersystems-iris-application-5-minutes
InterSystems IRIS REST APIへのアップロードREST APIによるファイル保存https://community.intersystems.com/post/upload-intersystems-iris-rest-api

InterSystems 環境の管理と設定

IRIS環境を適切に管理・設定することは、ユーザーが使用するアプリケーションのパフォーマンス、セキュリティ、可用性、信頼性にとって不可欠です。これらの記事は、これを行うための優れたヒントを与えてくれるでしょう。

名称概要URL
InterSystemsデータプラットフォームにおける容量計画およびパフォーマンスのシリーズのインデックス性能とパフォーマンスの向上https://jp.community.intersystems.com/node/477596
InterSystems Cache での %Installer によるアプリケーションのデプロイメント%Installer によるネームスペース、データベース、およびアプリケーションの構成の作成https://jp.community.intersystems.com/node/478966
InterSystems IRISによる水平方向のスケーラビリティIRISインスタンスを設定し、水平方向のスケーラビリティの実現https://jp.community.intersystems.com/node/477591
Raspberry Pi Raspberry で動作する InterSystems Iris Fhirserver が FHIRserver として動作Raspberry PI内部でIRISの動作https://jp.community.intersystems.com/node/516361
バーチャルIPアドレスを使用しないデータベースミラーリングVIPによるミラーの設定https://jp.community.intersystems.com/node/493401
DockerによるApache Web GatewayWebアプリケーションのSSLとWeb Gatewayの設定https://jp.community.intersystems.com/node/542181
IRISにおけるSAMLとの連携Webサービス向けSAMLhttps://community.intersystems.com/post/work-saml-iris
SYSTEM.Encryption クラスの習得IRISによる暗号化・復号化https://jp.community.intersystems.com/node/523406

Docker と Cloud

新しいアプリケーション・アーキテクチャは、コンテナ Docker と Cloud において動作し、弾力的なスケーラビリティ、インストール、設定、プロビジョニング時間の短縮、インフラの複雑性とコストの削減を実現することを目的としています。これらの記事を読んで、IRISをクラウド化する方法を学んでください。

名称概要URL
Kubernetesにおけるミラーリングを使用しない高可用性IRISデプロイKubernetesによるIRISをクラウドクラスターで利用するhttps://jp.community.intersystems.com/node/490971
Amazon Web Services (AWS)のためのInterSystems IRISリファレンス・アーキテクチャAWSでのIRIShttps://jp.community.intersystems.com/node/481326
Microsoft Azure Resource Manager (ARM)のInterSystems製リファレンス・アーキテクチャ安価なマシン(ARM machine)を使ったAzureでのIRIShttps://jp.community.intersystems.com/node/478971
Dockerfileと仲間たち、またはInterSystems IRISでのObjectScriptプロジェクトの実行と共同作業の方法Dockerプロジェクトにおける重要なファイルについて知ることhttps://community.intersystems.com/post/dockerfile-and-friends-or-how-run-and-collaborate-objectscript-projects-intersystems-iris
CloudFormationテンプレートを使用したAWS向けInterSystems IRISデプロイメントガイドCloudFormationを使ったAWSで使うIRIShttps://jp.community.intersystems.com/node/486206
Google Cloud Platform(GCP) におけるInterSystems IRIS のリファレンス・アーキテクチャGoogle Cloudで使うIRIShttps://jp.community.intersystems.com/node/479806
InterSystems IRISでAWS Glueの使用IRISとAWS Glue(AWSのETLツール)の利用https://jp.community.intersystems.com/node/485971
AmazonのEKSとIRIS。高可用性とバックアップAWSによるHAで使うIRIShttps://jp.community.intersystems.com/node/501186 AWSによるHAでのIRIS
コンテナでの InterSystems レポートの動かしてみるDockerに関するIRISのレポートhttps://jp.community.intersystems.com/node/501656
InterSystems IRIS を Kubeless を使って FaaS モードで実行Kubernetesで使うIRIShttps://jp.community.intersystems.com/node/523446
InterSystems Kubernetes Operator Deep Dive ‐ Kubernetes Operatorの紹介Kubernetesで使うIRIShttps://community.intersystems.com/post/intersystems-kubernetes-operator-deep-dive-introduction-kubernetes-operators
クラウドホストのスケーリングとInterSystems IRISの再構築AWS、Azure、またはGCPでのIRISのスケーリングhttps://community.intersystems.com/post/scaling-cloud-hosts-and-reconfiguring-intersystems-iris
Amazon EKSを用いたシンプルなIRISベースのWebアプリケーションのデプロイメントAWSで使うIRIShttps://jp.community.intersystems.com/node/478961

VSCode

VSCodeは世界で最も使われているIDEの1つです。IRISはこのIDEをフルサポートしています。以下の記事をご覧ください。

名称概要URL
VSCode-ObjectScriptのGitHubでの使用Web Github VSCodeでIRISアプリの開発https://jp.community.intersystems.com/node/510736
IRISによるGitHubのコードスペースGithubでIRISアプリの開発https://jp.community.intersystems.com/node/510736
VSCodeのヒントとコツ - SOAPウィザードVSCodeにショートカットのオプションの作成https://community.intersystems.com/post/vscode-tips-tricks-soap-wizard
VS Codeへの独自のスニペットの追加スニペットの作成https://community.intersystems.com/post/adding-your-own-snippets-vs-code

SQL

SQLは、リレーショナルデータベースを扱うのに最もよく使われる言語の1つです。これらの記事は、クエリの実行方法とデータの永続性を示しています。

名称概要URL
フリーテキスト検索:SQL開発者が隠しているテキストフィールドの検索方法*インデックスの活用で高度な検索を促進https://jp.community.intersystems.com/node/479321
日付範囲クエリのSQLパフォーマンスの向上日付を使ったSQLクエリの実行https://jp.community.intersystems.com/node/479286
スタティックWHERE条件永続的なクラ使うWherehttps://community.intersystems.com/post/static-where-conditions
2021.2 SQL機能スポットライト - ランタイムプランの選択ランタイムSQL実行プランの選択https://jp.community.intersystems.com/node/510746
2020.1 の新機能:ユニバーサルクエリキャッシュSQL Cachehttps://jp.community.intersystems.com/node/535211
マテリアライズド・ビュー永続的なクラスの中にビューの作成https://community.intersystems.com/post/materialized-views
SQLを使ったデバッグのコツSQLコマンドのデバッグhttps://community.intersystems.com/post/debugging-trick-sql
ClassQueries()をテーブルとして使用ビューの作成https://community.intersystems.com/post/using-classqueries-tables
M:Nの関係N対Nの関係性のマッピングhttps://community.intersystems.com/post/mn-relationship
IRISでCOVIDにたいしてのAWS S3データをSQLテーブルとして読み込むAWS S3からCSVデータをIRISのテーブルに取得https://community.intersystems.com/post/reading-aws-s3-data-covid-sql-table-iris
知っておくと便利なクエリパフォーマンスのコツ - Tune TableSQLチューニングhttps://jp.community.intersystems.com/node/535211
データストレージ:開発がうまくいくために知っておくべき情報より高いパフォーマンスを得るために、データストレージ部を永続的なクラスで構成するhttps://community.intersystems.com/post/data-storage-information-you-must-know-make-good-decisions-when-developing
日付範囲クエリのSQLパフォーマンスを改善する vol2SQLクエリの日付に関するチューニングhttps://jp.community.intersystems.com/node/479291
スクロール可能なResultSetのページネーションのサンプルSQLの結果をページ分割する(コメントも参照)https://community.intersystems.com/post/scrollable-resultset-pagination-sample
1日目 InterSystems ObjectsとSQLを用いた開発InterSystems IRISへのSQLに関するコンセプトhttps://community.intersystems.com/post/day-1-developing-intersystems-objects-and-sql
SQLgatewayを利用したDBマイグレーションPostgreSQL、MySQL、その他のデータベースからIRISへのマイグレーションhttps://jp.community.intersystems.com/node/518861
InterSystems IRIS の既存のテーブルに CSV のインポートCSVからSQLテーブルへのインポートhttps://community.intersystems.com/post/importing-csv-existing-table-intersystems-iris
データベースの4つのAPISQLの APIhttps://community.intersystems.com/post/four-database-apis
アトミックでない属性のインデックス作成高度なインデックスのオプションの作成https://jp.community.intersystems.com/node/486236
インデックスについてインデックス作成の基礎知識https://jp.community.intersystems.com/node/492126
Dynamic SQLからDynamic ObjectへDynamicSQLの使用https://community.intersystems.com/post/dynamic-sql-dynamic-object
データ移行ツール - その1:PostgresからIRISへ一般的なデータベースからIRISデータベースへの移行方法を紹介する連載記事https://jp.community.intersystems.com/node/518871

アナリティクスとビジネスインテリジェンス(BI)

アナリティクスとBIは、グラフ、ダッシュボード、サマリー、詳細表などのデータ分析、およびアナリスト・ユーザーによるナビゲーションとデータ探索に基づいて意思決定を行うことを可能にします。ここでは、IRISを使った分析アプリケーションの構築方法を紹介します。

名称概要URL
InterSystems IRISのCOVID-19アナリティクスInterSystems IRISにおけるCOVID-19アナリティクスhttps://community.intersystems.com/post/covid-19-analytics-intersystems-iris
DeepSeeトラブルシューティングガイド不具合修正https://jp.community.intersystems.com/node/542206
AnalyzeThis - InterSystems BIへのクイックスタートInterSystems BIへのクイックスタートhttps://community.intersystems.com/post/analyzethis-%E2%80%93-quick-start-intersystems-bi
InterSystems IRIS用のPower BIコネクタ パート1Power BIでIRISのデータの利用https://jp.community.intersystems.com/node/482606
DeepSee でのポートレットの作成IRIS BIによるアナリティクスポートレットhttps://community.intersystems.com/post/creating-portlets-deepsee
Game Of Throne Analytics、またはアリア スタークリストの長さアナリティクスのサンプルhttps://community.intersystems.com/post/game-throne-analytics-or-how-long-aryas-stark-list
DeepSee Web。AngularJSによるInterSystems Analyticsのビジュアライゼーション。第 1 部Angularを使用するWebダッシュボードhttps://community.intersystems.com/post/deepsee-web-intersystems-analytics-visualization-angularjs-part-1
IRIS でアナリティクスソリューションを構築するIRISでアナリティクスを行うための主なオプションの紹介https://jp.community.intersystems.com/node/501571

グローバル

IRIS では、SQL、クラス、JSON ドキュメント、BI キューブ、その他のカスタム形式など、データを柔軟に保存および取得するための重要なメカニズムとして、グローバルが使用されています。以下の記事で、その方法を垣間見てください:

名称概要URL
グローバルをクラスにマッピングする技術 :1 / 3グローバルの SQL テーブルおよびオブジェクトへのマッピングhttps://jp.community.intersystems.com/node/486176
グローバルは、データ管理の魔法の剣。第1回グローバルに関する基礎知識https://jp.community.intersystems.com/node/476486
GlobalToJSON-embeddedPython-pureグローバルをJSONへの書き出しhttps://community.intersystems.com/post/globaltojson-embeddedpython-pure
InterSystems IRIS のグローバルを使ったトランザクショングローバルパーシスタンスのトランザクション管理https://jp.community.intersystems.com/node/486476
グローバルによる マインドマップの保存グローバルを使ってマインドマップデータの永続化https://jp.community.intersystems.com/node/516226

セキュリティ

どのようなアプリケーションでも、セキュリティを確保することは非常に重要です。セキュリティは、アクセスや承認の管理、トランザクションの追跡と監査、保存および転送されるコンテンツの暗号化、感性的なリソースの保護を保証するための正しい設定パラメータに関連しています。これらの記事を読んで、セキュリティを確立する方法について理解を深めてください。

名称概要URL
InterSystems IRIS Open Authorization Framework (OAuth 2.0) の実装 - 第1回OAuthの使用https://jp.community.intersystems.com/node/478821
WebのデバッグCSPおよびRESTアプリのデバッグhttps://jp.community.intersystems.com/node/501166
InterSystems IRIS のクラスクエリ永続クラス内部でのSQL Queryの定義https://jp.community.intersystems.com/node/483716
TLS/SSLでOSの証明書ストアの使用SSLを行うためにOSの証明書の使用https://community.intersystems.com/post/using-os-certificate-store-tlsssl
インテグリティチェック :スピードアップまたはスピードダウンインテグリティの確保https://community.intersystems.com/post/integrity-check-speeding-it-or-slowing-it-down
データ変更の追跡 - 監査ログ - 1 / 2監査データの保存https://jp.community.intersystems.com/node/483691
TLS/SSL/HTTPS による管理ポータル(プライベート Web サーバー)の運用IRIS Web サーバーへの SSL の設定https://community.intersystems.com/post/running-management-portal-private-web-server-over-tlssslhttps
OAuth認証とInterSystems IRIS:信頼プロトコルのテイム化OAuthの使用https://community.intersystems.com/post/oauth-https://jp.community.intersystems.com/node/493421
SOAP(Web)サービスでのOauth2の利用についてSOAPサービスにおけるOauthの設定https://jp.community.intersystems.com/node/483696
DeepSee: セキュリティの設定 - 1/5IRIS BIにおけるセキュリティhttps://community.intersystems.com/post/deepsee-setting-security-part-1-5
システムのセキュリティレベルの変更についてデフォルトでセキュリティhttps://community.intersystems.com/post/changes-security-level-system

DevOps

DevOpsとは、ソースコードの開発(Dev)から本番運用(Ops)への高速かつ高品質な移行を自動化することを可能にするプラクティスやツールを採用する方法です。IRISでその方法をご覧ください。

名称概要URL
GitLabを使ったInterSystemsソリューションの継続的デリバリー - 第1回:GitGitLabによる継続的デリバリーhttps://jp.community.intersystems.com/node/476396
InterSystems ObjectScripts パッケージ・マネージャの紹介ZPMを使用して、アプリケーション内のサードパーティパッケージを設定およびインストールhttps://jp.community.intersystems.com/node/486186
ZPMshow - 疲れた指のためのヘルパーZPM - IRISパッケージマネージャの使用方法https://community.intersystems.com/post/zpmshow-helper-tired-fingers
プログラムによるミラーのセットアップ方法新しいミラーの作成を自動化するhttps://jp.community.intersystems.com/node/516091
ObjectScript パッケージマネージャにおけるユニットテストとテストカバレッジObjectScriptのコード品質のためのUnit Testsの作成https://jp.community.intersystems.com/node/516111
DockerとMergeCPFを使ったシャードクラスターの展開cpfファイルによる設定の自動化https://community.intersystems.com/post/deploying-sharded-cluster-docker-and-mergecpf
Caché ObjectScript クイックリファレンスObjectScriptリファレンスpdfドキュメントhttps://community.intersystems.com/post/cach%C3%A9-objectscript-quick-reference
ZPMモジュールの解剖学:InterSystems Solution のパッケージングZPMを使用してデプロイメントの自動化https://jp.community.intersystems.com/node/487071
IRISコンテナへのVSCodeの追加VSCodeをdockerインスタンスに埋め込むhttps://community.intersystems.com/post/adding-vscode-your-iris-container
InterSystems IRIS用の新しいデータベース、ネームスペース、およびWebアプリケーションをプログラムによって作成する方法データベースとネームスペースの作成の自動化https://community.intersystems.com/post/how-create-new-database-namespace-and-web-application-intersystems-iris-programmatically
ユニットテスト: ObjectScript コードの品質ユニットテストによる品質保証https://community.intersystems.com/post/unit-tests-quality-your-objectscript-code
インターシステムズ開発者コミュニティのDockerイメージDockerコミュニティイメージhttps://community.intersystems.com/post/some-intersystems-developer-community-docker-images

インターオペラビリティ

IRISは、強力なデータおよびアプリケーションのインタラクティブなバスを備えています。以下の記事でその使い方をご覧ください。

名称概要URL
EnsembleからTelegramでアラートの送信テレグラムにデータを送信するためのプロダクションhttps://community.intersystems.com/post/sending-alerts-ensemble-telegram
[初めてのInterSystems IRIS] インターオペラビリティを使ってみようビジネスサービス、オペレーション、プロセス、プロダクションの作成https://jp.community.intersystems.com/node/483021
Embedded PythonによるInterSystems IRISのインターオペラビリティーPythonによるビジネスサービス、オペレーション、プロセス、プロダクションの作成https://jp.community.intersystems.com/node/518846
Ensemble / Interoperabilityトレーニングコースプロダクションの作り方を学ぶのに最適なサンプルhttps://community.intersystems.com/post/ensemble-interoperability-training-course
プログラムによるインターオペラビリティーのサンプルPythonまたはObjectScriptを使用したプログラムによるプロダクションhttps://jp.community.intersystems.com/node/521511
フォルダ内のファイルのリスティングフォルダー内のファイルをリスト化するhttps://community.intersystems.com/post/listing-files-folder
.Net/Java Gatewayのコンテナ化(またはKafka統合のデモ)Javaまたは.Net Native APIを使用したKafkaサポートhttps://jp.community.intersystems.com/node/542191
PEXを使用した.NETまたはJavaでのIRIS統合の実装PEXによるJavaまたは.Netを使ったプロダクションの作成https://community.intersystems.com/post/implementing-iris-integrations-net-or-java-using-pex
Java Business HostからPEXへの移行PEXの使用https://jp.community.intersystems.com/node/486231
Tesseract OCRとJava Gatewayの使用についてJava PEXの使用https://community.intersystems.com/post/using-tesseract-ocr-and-java-gateway
PEXのビジネスオペレーションを作成についてCreate Java PEX Business Operationhttps://community.intersystems.com/post/creating-pex-business-operation
OCRとNLPを統合したInterSystems IRISJava PEX のサンプルhttps://community.intersystems.com/post/ocr-and-nlp-together-intersystems-iris
HTTP Adapterを使用したカスタムインターオペラビリティビジネスサービスの作成ビジネスサービスの作成https://community.intersystems.com/post/creating-custom-interoperability-business-service-using-http-adapter

Native API

IRISは、市場で最も使用されているプログラミング言語(Java、Javascript/NodeJS、.Net、C++、Python)を使用することに前向きです。これを実現するために、これらの言語ごとにNative APIを使用しています。以下の記事をご覧ください。

名称概要URL
Docker Micro ServerとしてIRIS Native APIを使用したWebSocket Client JSIRISとNodeJSを使ってWebSocketを行うhttps://jp.community.intersystems.com/node/507846
ObjectScript用IRIS Native APINative APIの使用https://community.intersystems.com/post/iris-native-api-objectscript
Node.jsでのZPMの使用Node.jsプロジェクトでのZPMの使用https://jp.community.intersystems.com/node/507866
テキストファイルからPDFファイルの作成PDFファイルの生成用Java Native APIhttps://community.intersystems.com/post/creating-pdf-text-file
InterSystems IRISを使った開発を1分以内に始める方法IRISを使った開発の開始https://community.intersystems.com/post/how-start-development-intersystems-iris-less-minute
Python + IRIS Globals を使ったブログの作成Python Native API用ブログhttps://jp.community.intersystems.com/node/501856
0
2 245
質問 Yuji Ohata · 4月 13, 2023

こんにちは、皆さま。
業務でIRISを用いて開発を行っている者です。

現在、Embedded Pythonを用いて開発を行おうとしているのですが、
別のNMSPに存在するグローバルをiris.gref()で参照する方法がわかりませんでした。

> iris.gref("^[NMSP]GBL")   <-----こうしても自身のNMSPのグローバルを参照してしまう。

諦めてznでネームスペースを切り替えてみようかな、とも思ったのですが、
python上でznをかける方法もよくわからず、対応方法に悩んでいます。

どなたか、上記の対応方法についてご存じな方はいらっしゃいませんでしょうか?

5
1 221
記事 Toshihiko Minamoto · 6月 29, 2023 13m read

         

コミュニティの皆さん、こんにちは。
この記事では、InterSystems Embedded Python の使用方法を説明します。以下のトピックが含まれます。

  • 1- Embedded Python の概要
  • 2- Embedded Python の使用方法
    • 2.1- ObjectScript から Python ライブラリを使用する
    • 2.2- Python から InterSystems API を呼び出す
    • 2.3- ObjectScript と Python を同時に使用する
  • 3- Python 組み込み関数の使用
  • 4- Python モジュール/ライブラリ 
  • 5- Embedded Python のユースケース
  • 6- まとめ

では、概要から始めましょう。

 

1- Embedded Python の概要

Embedded Python は、Python 開発者が InterSystems IRIS の全データと全機能に直接アクセスできるようにする、InterSystems IRIS データプラットフォームの機能です。

InterSystems IRIS には、データプラットフォーム内で解釈、コンパイル、および実行される ObjectScript と呼ばれる強力なプログラミング言語が組み込まれています。

ObjectScipt は InterSystems IRIS のコンテキスト内で実行されるため、データプラットフォームのメモリとプロシージャ呼び出しに直接アクセスできます。

Embedded Python は、InterSystems IRIS プロセスコンテキスト内で Python コードを実行を可能にする Python プログラミング言語の拡張機能です。

ObjectScript と Python のいずれも同じオブジェクトメモリで動作するため、Python オブジェクトは ObjectScript オブジェクトを単にエミュレートするのではなく、ObjectScipt オブジェクトであると言えます。

これらの言語の共平等性により、ジョブに最適な言語か、アプリケーションの記述に最も使いやすい言語を選択することができます。

 

2- Embedded Python の使用方法

Embedded Python を使用する場合、3 つの異なる方法でコードを記述できます。

2.1- ObjectScript から Python ライブラリを使用する

まず、通常の .py ファイルを記述し、InterSystems IRIS コンテキストからそれを呼び出します。 この場合、データプラットフォームは Python プロセスを起動し、IRIS と呼ばれるモジュールをインポートできるようにします。これにより、Python プロセスが IRIS カーネルに自動的に接続されるため、Python コードのコンテキストから ObjectScript のすべての機能にアクセスできるようになります。

2.2- Python から InterSystems API を呼び出す

次に、通常の ObjectScript コードを記述し、%SYS.Python パッケージを使って Python オブジェクトをインスタンス化します。 この ObjectScript パッケージを使うと、Python モジュールとライブラリをインストールし、ObjectScript 構文でコードベースを操作できるようになります。
%SYS.Python パッケージを使うと、ObjectScript 開発者は Python の知識が無くてもリッチな Python ライブラリエコシステムを ObjectScript コードで使用できるようになります。

2.3- ObjectScript と Python を同時に使用する

最後に、InterSystems クラス定義を作成し、Python でメソッドを記述します。 そのメソッドを呼び出すと、Python インタープリターが起動します。 このメソッドは、メリットとして、それを含むクラスのインスタンスへの参照を使って、Python コードのそのブロックの self キーワードを埋めることができます。 また、Python を使って InterSystems クラスにクラスメソッドを書き込むことで、SQL で、テーブルに新しい行が追加されたなどの異なるデータエントリイベントを処理するメソッドを簡単に実装できます。
カスタムストアドプロシージャを Python で迅速に開発することも可能です。

ご覧のとおり、Embedded Python を使用すると、パフォーマンスを犠牲にすることなく、ジョブに最適なプログラミング言語を選択できます。

3- Python 組み込み関数の使用

Python インタープリターには、常に利用できる多数の関数と型が組み込まれています。 以下に、アルファベット順でリストしています。

組み込み関数
AELR
abs()enumerate()len()range()
aiter()eval()list()repr()
all()exec()locals()reversed()
any()round()
anext()FM
ascii()filter()map()S
float()max()set()
Bformat()memoryView()setattr()
bin()frozenset()min()slice()
breakpoint()GNstaticmethod()
bytearray()getattr()next()str()
bytes()globals()sum()
Osuper()
CHobject()
callable()hasattr()oct()T
chr()hash()open()tuple()
classmethod()help()ord()type()
compile()hex()
complex()PV
Ipow()vars()
Did()print()
delattr()input()property()Z
dict()int()zip()
dir()isinstance()
divmod()issubclass()-
iter()__import__()

Python 組み込み 関数の使用

Python 組み込み関数を使用するには、"builtins" をインポートする必要があります。その後、関数を呼び出せるようになります。

set builtins = ##class(%SYS.Python).Import("builtins")

Python の print() 関数は、実際には組み込みモジュールのメソッドであるため、ObjectScript からこの関数を使用できるようになりました。

USER>do builtins.print("hello world!")
hello world!
USER>set list = builtins.list()
 
USER>zwrite list
list=5@%SYS.Python  ; []  ; <OREF>

同様に、help() メソッドを使って、リストオブジェクトのヘルプを取得できます。

USER>do builtins.help(list)
Help on list object:
class list(object)
 |  list(iterable=(), /)
 |
 |  Built-in mutable sequence.
 |
 |  If no argument is given, the constructor creates a new empty list.
 |  The argument must be an iterable if specified.
 |
 |  Methods defined here:
 |
 |  __add__(self, value, /)
 |      Return self+value.
 |
 |  __contains__(self, key, /)
 |      Return key in self.
 |
 |  __delitem__(self, key, /)
 |      Delete self[key].

 

4- Python モジュールまたはライブラリ

一部の Python モジュールまたはライブラリはデフォルトでインストールされるため、すでに利用することができます。 help("module") 関数を使うと、これらのモジュールを表示できます。
Python libraries list output 1

Python モジュールまたはライブラリのインストール

これらのモジュールとは別に、Python には数百ものモジュールとライブラリがあり、pypi.org で確認できます。Python Package Index(PyPI)は Python プログラミング言語のソフトウェアリポジトリです)

他のライブラリが必要な場合は、intersystems irispip コマンドを使ってライブラリをインストールする必要があります。

たとえば、Pandas は Python データ分析ライブラリです。 以下のコマンドは、パッケージインストーラーの irispip を使用して、Windows システムに Pandas をインストールします。

C:\InterSystems\IRIS\bin>irispip install --target C:\InterSystems\IRIS\mgr\python pandas

C:\InterSystems は InterSystems インストールディレクトリに置き換えられることに注意してください。

5- Embedded Python のユースケース

5.1- Python Reportlab ライブラリを使った PDF の印刷

irispip コマンドを使用して Reportlab ライブラリをインストールしてから、objectscript 関数を作成します。

ファイルの場所を指定すると、以下の CreateSamplePDF() という ObjectScript メソッドによって、サンプル PDF ファイルが作成され、その指定場所に保存されます。

Class Demo.PDF
{

ClassMethod CreateSamplePDF(fileloc As%String) As%Status
{
    set canvaslib = ##class(%SYS.Python).Import("reportlab.pdfgen.canvas")
    set canvas = canvaslib.Canvas(fileloc)
    do canvas.drawImage("C:\Sample\isc.png", 150, 600)
    do canvas.drawImage("C:\Sample\python.png", 150, 200)
    do canvas.setFont("Helvetica-Bold", 24)
    do canvas.drawString(25, 450, "InterSystems IRIS & Python. Perfect Together.")
    do canvas.save()
}

}

メソッドの最初の行では、ReportLab の pdfgen サブパッケージから canvas.py ファイルをインポートしています。 コードの 2 行目は、Canvas オブジェクトをインスタンス化し、InterSystems IRIS オブジェクトのメソッド呼び出しと同じ方法で、メソッドを呼び出しています。

その後、通常の方法でメソッドを呼び出せるようになります。

do ##class(Demo.PDF).CreateSamplePDF("C:\Sample\hello.pdf")

以下の PDF が生成され、指定された場所に保存されます。
InterSystems ロゴ、Python ロゴ、および InterSystems and Python のテキストを含む 1 ページ PDF。 併用による完璧な機能。

 

5.2- Python Qrcode ライブラリを使った QR コードの生成

QR コードを生成するには、irispip コマンドを使用して Qrcode ライブラリをインストールする必要があります。次に、以下のコードを使用すると、QR コードを生成できます。

 

5.3- Python Folium ライブラリを使った地理的位置情報の取得

地理データを取得するには、irispip コマンドを使用して Folium ライブラリをインストールする必要があります。次に、以下の objectscript 関数を作成します。

Class dc.IrisGeoMap.Folium Extends%SwizzleObject
{

// Function to print Latitude, Longitude and address details ClassMethod GetGeoDetails(addr As%String) [ Language = python ]
{
    from geopy.geocoders import Nominatim
    geolocator = Nominatim(user_agent="IrisGeoApp")
    try:
        location = geolocator.geocode(addr)
        print("Location:",location.point)
        print("Address:",location.address)
        point = location.point
        print("Latitude:", point.latitude)
        print("Longitude:", point.longitude)
    except:
        print("Not able to find location")
}
}

IRIS ターミナルに接続して以下のコードを実行します

do ##class(dc.IrisGeoMap.Folium).GetGeoDetails("Cambridge MA 02142")

以下が出力されます。

画像

 

5.4- Python Folium ライブラリを使ったインタラクティブ地図への場所の生成とマーキング

同じ Python Folium 伊良部らりを使用して、インタラクティブ地図に場所を生成し、それをマーキングします。以下の objectsctipt 関数によって、これを実行します。

ClassMethod MarkGeoDetails(addr As%String, filepath As%String) As%Status [ Language = python ]
{
    import folium
    from geopy.geocoders import Nominatim
    
    geolocator = Nominatim(user_agent="IrisGeoMap")
    #split address in order to mark on the map
    locs = addr.split(",")
    if len(locs) == 0:
        print("Please enter address")
    elif len(locs) == 1:
        location = geolocator.geocode(locs[0])
        point = location.point
        m = folium.Map(location=[point.latitude,point.longitude], tiles="OpenStreetMap", zoom_start=10)
    else:
        m = folium.Map(location=[20,0], tiles="OpenStreetMap", zoom_start=3)
    
    for loc in locs:
        try:
            location = geolocator.geocode(loc)
            point = location.point
            folium.Marker(
                    location=[point.latitude,point.longitude],
                    popup=addr,
                ).add_to(m)         
        except:
            print("Not able to find location : ",loc) 
              
    map_html = m._repr_html_()
    iframe = m.get_root()._repr_html_()
    fullHtml = """
             
                
                    
                     """
    fullHtml = fullHtml + iframe            
    fullHtml = fullHtml + """                                             
                
                
    """try:
        f = open(filepath, "w")
        f.write(fullHtml)
        f.close()
    except:
        print("Not able to write to a file")
}

IRIS ターミナルに接続し、MarkGeoDetails 関数を呼び出します

dc.IrisGeoMap.Folium クラスの MarkGeoDetails() 関数を呼び出します。
この関数には、以下の 2 つのパラメーターが必要です。

  1. 場所("," 区切りで、複数の場所を渡すことができます)
  2. HTML ファイルパス

以下のコマンドを実行し、地図に Cambridge MA 02142、NY、London、UAE、Jeddah、Lahore、および Glasgow の場所をマークして、 "irisgeomap_locations.html" ファイルとして保存します。

do ##class(dc.IrisGeoMap.Folium).MarkGeoDetails("Cambridge MA 02142,NY,London,UAE,Jeddah,Lahore,Glasgow","d:\irisgeomap_locations.html")

上記のコードによって、以下のインタラクティブ HTML ファイルが生成されます。

画像

 

5.5- Python Pandas ライブラリを使ったデータ分析

irispip コマンドを使用して Pnadas ライブラリをインストールする必要があります。次に、以下のコードを使用すると、データが表示されます。

 

6- まとめ

InterSystems Embedded Python(IEP)は、Python コードと InterSytems アプリケーションをシームレスに統合できる強力な機能です。 IEP を使用すると、Python で利用可能な広範なライブラリとフレームワークを活用して、InterSystems アプリケーションの機能を強化できます。 この記事では、IEP の主な機能とメリットを説明しました。

IEP は、InterSystems アプリケーション内から Python オブジェクトを操作し、Python コードを実装できるようにする一連のライブラリとして実装されています。 これにより、単純で有効な方法によって、Python コードを InterSystems アプリケーションに統合できるため、データ分析、機械学習、自然言語処理など、InterSystems ObjectScript での実装が困難なタスクを実行できるようになります。

IEP を使用する主なメリットの 1 つには、Python と InterSysems の間のギャップのかけ渡しを得られることが挙げられます。 このため、両方の言語の持つ力を使って、両分野の長所を組み合わせた強力なアプリケーションを作成しやすくなります。

IEP には、Python の機能を活用して、InterSystems アプリケーションの機能を拡張する方法も備わっています。 つまり、InterSystems ObjectScript で実装するには困難なタスクに、Python で利用できる膨大な数のライブラリをフレームワークを利用して実行できます。

InterSystems Embedded Python には、Python の機能を活用して、InterSystems アプリケーションの機能を拡張する強力な方法が備わっています。 Python コードを InterSystems アプリケーションに統合することで、Python で利用できる膨大な数のライブラリとフレームワークを利用し、InterSystems ObjectScript での実装が困難な複雑なタスクを実行できます。

以上です!

0
0 568
お知らせ Mihoko Iijima · 6月 12, 2023

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

InterSystems グランプリコンテスト2023 では、InterSystems IRIS data platform を使用する機能であればどんな内容でもご応募いただけます。

以下の機能を含めた場合、ボーナスポイントを獲得できます。

詳細は以下の通りです。

  • LLM AI や LangChain の使用:Chat GPT、Bard など - 6ポイント
  • InterSystems FHIR SQL Builder- 5ポイント
  • InterSystems FHIR - 3ポイント
  • IntegratedML - 4ポイント
  • Native API - 3ポイント
  • Embedded Python - 4ポイント
  • Interoperability - 3ポイント
  • Production EXtension(PEX) - 2ポイント
  • Adaptive Analytics (AtScale) のキューブの利用 - 3ポイント
  • Tableau, PowerBI, Logi の利用 - 3ポイント
  • InterSystems IRIS BI - 3ポイント
  • Docker container の利用 - 2ポイント 
  • ZPM Package によるデプロイ - 2ポイント
  • オンラインデモ - 2ポイント
  • ユニットテスト - 2ポイント
  • InterSystems Community Idea に投稿された内容の実装 - 4ポイント
  • コミュニティ(USコミュニティ)に記事を投稿する(最初の記事) - 2ポイント
  • コミュニティ(USコミュニティ)に2つ目の記事を投稿する - 1ポイント
  • Code Qualityをパスする - 1ポイント
  • はじめてチャレンジされた方 - 3ポイント
  • YouTubeにビデオを公開- 3ポイント
0
0 107
記事 Mihoko Iijima · 6月 1, 2023 7m read

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

先日のウェビナーでご紹介した「ワークフローコンポーネント」をお試しいただけるサンプルを公開しました。👉 https://github.com/Intersystems-jp/WorkFlow-DC

《サンプルのテーマ》

店舗で販売している商品に付けるPOPメッセージ候補を予めテーブルに登録できる仕組みが既にある、と仮定しています。

IRISの Interoperability を利用してPOPメッセージ候補が登録されるテーブルに対して一定間隔でSELECT文を実行し、未処理のメッセージを取得します。
新たなレコードが存在する場合、ワークフローコンポーネントを利用して担当者に審査を依頼します。

担当者は、ワークフローユーザポータルを使用して、POPメッセージ候補の承認/却下を指示できるようにしています。

0
0 206
記事 Mihoko Iijima · 5月 30, 2023 2m read

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

%SYSTEMパッケージには沢山の便利なシステムクラスがあり、Embedded Pythonでも一般クラスと同様に%SYSTEMパッケージ以下クラスを操作できます(iris.cls("クラス名").メソッド名()で呼び出せます)。

ObjectScriptでは、$SYSTEM特殊変数を利用して、%SYSTEMパッケージ以下クラスのメソッドを呼び出すことができますが、Embedded Pythonでは、iris.system を利用して実行することができます。

以下実行例をご紹介します。

現在のネームスペースを取得する

一般クラスと同じ呼び出し方の例

iris.cls("%SYSTEM.SYS").NameSpace()

iris.systemを利用する例

iris.system.SYS.NameSpace()

 

binディレクトリのパスを返す

一般クラスと同じ呼び出し方の例

iris.cls("%SYSTEM.Util").BinaryDirectory()

iris.systemを利用する例

iris.system.Util.BinaryDirectory()

 

SQL関連をまとめたSQLクラスの例は以下の通りです。

YYYY-MM-DDから$horolog形式の日付を返す

一般クラスと同じ呼び出し方の例

0
0 128
記事 Toshihiko Minamoto · 5月 23, 2023 8m read

Web スクレイピングとは:

簡単に言えば、Web スクレイピングWeb ハーベスティング、または Web データ抽出とは、Web サイトから大量のデータ(非構造化)を収集する自動プロセスです。 ユーザーは特定のサイトのすべてのデータまたは要件に従う特定のデータを抽出できます。 収集されたデータは、さらに分析するために、構造化された形式で保存することができます。

Web スクレイピングとは? — James Le

Web スクレイピングの手順:

  1. スクレイピングする Web ページの URL を見つけます。
  2. 検査により、特定の要素を選択します。
  3. 選択した要素のコンテンツを取得するコードを記述します。
  4. 必要な形式でデータを保存します。

たったそれだけです!!

Web スクレイピングに使用される一般的なライブラリ/ツール

  • Selenium - Web アプリケーションをテストするためのフレームワーク
  • BeautifulSoup – HTML、XML、およびその他のマークアップ言語からデータを取得するための Python ライブラリ
  • Pandas - データ操作と分析用の Python ライブラリ

Beauthiful Soup とは?

Beautiful Soup は、Web サイトから構造化データを抽出するための純粋な Python ライブラリです。 HTML と XML ファイルからデータを解析できます。 これはヘルパーモジュールとして機能し、利用できる他の開発者ツールを使って Web ページを操作する方法と同じ方法かより優れた方法で HTML と対話します。

  • lxmlhtml5lib などの使い慣れたパーサーと連携して、有機的な Python の方法で、解析ツリーを移動操作、検索、および変更できるようにするため、通常、プログラマーは数時間または数日間に及ぶ作業を節約できます。
  • Beautiful Soup のもう 1 つの強力で便利な機能は、フェッチされるドキュメントを Unicode に変換し、送信されるドキュメントを UTF-8 に変換するインテリジェンスです。 ドキュメント自体にエンコーディングが指定されていないか、Beautiful Soup がエンコーディングを検出できない場合を除き、開発者がその操作に注意する必要はありません。
  • 他の一般的な解析またはスクレイピング手法と比較した場合も高速と見なされています。

今日の記事では、Embedded Python と Object Script を使用して、ae.indeed.com にある Python の求人情報と企業をスクレイピングします。

ステップ 1 - スクレイピングする Web ページの URL を見つけます。

Url = https://ae.indeed.com/jobs?q=python&l=Dubai&start=0

スクレイピングするデータのある Web ページは以下のようになります。

  単純化と学習の目的で、"Job Title"(役職)と "Company"(会社)を抽出します。出力は以下のスクリーンショットのようになります。

 

以下の 2 つの Python ライブラリを使用します。

  • requests Requests は、Python プログラミング言語の HTTP ライブラリです。 プロジェクトの目標は、HTTP リクエストを単純化し、人間が読みやすくすることです。  
  • bs4 for BeautifulSoup Beautiful Soup は、HTML と XML ドキュメントを解析するための Python パッケージです。 HTML からデータを抽出するために使用できる解析済みページの解析ツリーを作成します。Web スクレイピングに役立ちます。

以下の Python パッケージをインストールしましょう(Windows)。

irispip install --target C:\InterSystems\IRISHealth\mgr\python bs4

irispip install --target C:\InterSystems\IRISHealth\mgr\python requests

Python ライブラリを ObjectScript にインポートしましょう
 

Class PythonTesting.WebScraper Extends%Persistent
{

// pUrl = https://ae.indeed.com/jobs?q=python&l=Dubai&start=// pPage = 0ClassMethod ScrapeWebPage(pUrl, pPage)
{
    // imports the requests python libraryset requests = ##class(%SYS.Python).Import("requests")
    // import the bs4 python libraryset soup = ##class(%SYS.Python).Import("bs4")
    // import builtins package which contains all of the built-in identifiersset builtins = ##class(%SYS.Python).Import("builtins")
}

Requests を使って HTML データを収集しましょう。

注意: 「my user agent」でグーグル検索し取得した、ユーザーエージェント
URL は "https://ae.indeed.com/jobs?q=python&l=Dubai&start=" で、pPage はページ番号です。

Requests を使って URL に HTTP GET リクエストを行い、そのレスポンスを "req" に格納します。

set headers  = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"}
    set url = "https://ae.indeed.com/jobs?q=python&l=Dubai&start="_pPage
    
    set req = requests.get(url,"headers="_headers)

req オブジェクトには、Web ページから返された HTML が含まれます。

これを BeautifulSoup HTML パーサーで実行し、求人データを抽出できるようにします。

set soupData = soup.BeautifulSoup(req.content, "html.parser")
set title = soupData.title.text
W !,title

タイトルは以下のように表示されます

ステップ 2 - 検査し、必要な要素を選択します。

このシナリオでは、通常 <div> タグに含まれる求人リストに注目しています。ブラウザ内で要素を検査すると、その div クラスが見つかります。

ここでは、必要な情報は、「 <div class="cardOutline tapItem ... </div>」 に格納されています。

ステップ 3 - 選択した要素のコンテンツを取得するコードを記述します。

BeautifulSoup の find_all 機能を使用して、クラス名 "cardOutline" を含むすべての <div> タグを検索します。

//parameters to python would be sent as a python dictionaryset divClass = {"class":"cardOutline"}
set divsArr = soupData."find_all"("div",divClass...)

これによりリストが返されます。これをループ処理すると、Job Titles と Company を抽出できます。

###ステップ 4 - 必要なフォーマットでデータを保存/表示します。

以下の例では、データをターミナルに書き出します。

set len = builtins.len(divsArr)
    
W !, "Job Title",$C(9)_" --- "_$C(9),"Company"for i = 1:1:len {
    Set item = divsArr."__getitem__"(i - 1)
    set title = $ZSTRIP(item.find("a").text,"<>W")
    set companyClass = {"class_":"companyName"}
    set company = $ZSTRIP(item.find("span", companyClass...).text,"<>W")
    W !,title,$C(9)," --- ",$C(9),company
}

builtins.len() を使用して、divsArr リストの長さを取得していることに注意してください。

識別子名: ObjectScript と Python の識別子の命名規則は異なります。 たとえば、Python のメソッド名ではアンダースコア(_)を使用でき、_getitem_ や _class_ のようにいわゆる「ダンダー」といわれる特殊なメソッドや属性で実際に広く使用されています(「ダンダー」は「double underscore = 二重アンダースコア」の略です)。 このような識別子を ObjectScript で使用するには、二重引用符で囲みます:

識別子名に関する InterSystems ドキュメント

クラスメソッドの例

ClassMethod ScrapeWebPage(pUrl, pPage)
// pUrl = https://ae.indeed.com/jobs?q=python&l=Dubai&start=// pPage = 0ClassMethod ScrapeWebPage(pUrl, pPage)
{
    set requests = ##class(%SYS.Python).Import("requests")
<span class="hljs-keyword">set</span> soup = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%SYS.Python</span>).Import(<span class="hljs-string">"bs4"</span>)

<span class="hljs-keyword">set</span> builtins = <span class="hljs-keyword">##class</span>(<span class="hljs-built_in">%SYS.Python</span>).Builtins()

<span class="hljs-keyword">set</span> headers  = {<span class="hljs-string">"User-Agent"</span>: <span class="hljs-string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"</span>}
<span class="hljs-keyword">set</span> url = pUrl_pPage

<span class="hljs-keyword">set</span> req = requests.get(url,<span class="hljs-string">"headers="</span>_headers)

<span class="hljs-keyword">set</span> soupData = soup.BeautifulSoup(req.content, <span class="hljs-string">"html.parser"</span>)

<span class="hljs-keyword">set</span> title = soupData.title.text

<span class="hljs-keyword">W</span> !,title

<span class="hljs-keyword">set</span> divClass = {<span class="hljs-string">"class_"</span>:<span class="hljs-string">"cardOutline"</span>}
<span class="hljs-keyword">set</span> divsArr = soupData.<span class="hljs-string">"find_all"</span>(<span class="hljs-string">"div"</span>,divClass...)

<span class="hljs-keyword">set</span> len = builtins.len(divsArr)

<span class="hljs-keyword">W</span> !, <span class="hljs-string">"Job Title"</span>,<span class="hljs-built_in">$C</span>(<span class="hljs-number">9</span>)_<span class="hljs-string">" --- "</span>_<span class="hljs-built_in">$C</span>(<span class="hljs-number">9</span>),<span class="hljs-string">"Company"</span>
<span class="hljs-keyword">for</span> i = <span class="hljs-number">1</span>:<span class="hljs-number">1</span>:len {
        <span class="hljs-keyword">Set</span> item = divsArr.<span class="hljs-string">"__getitem__"</span>(i - <span class="hljs-number">1</span>)
        <span class="hljs-keyword">set</span> title = <span class="hljs-built_in">$ZSTRIP</span>(item.find(<span class="hljs-string">"a"</span>).text,<span class="hljs-string">"<>W"</span>)
        <span class="hljs-keyword">set</span> companyClass = {<span class="hljs-string">"class_"</span>:<span class="hljs-string">"companyName"</span>}
        <span class="hljs-keyword">set</span> company = <span class="hljs-built_in">$ZSTRIP</span>(item.find(<span class="hljs-string">"span"</span>, companyClass...).text,<span class="hljs-string">"<>W"</span>)
        <span class="hljs-keyword">W</span> !,title,<span class="hljs-built_in">$C</span>(<span class="hljs-number">9</span>),<span class="hljs-string">" --- "</span>,<span class="hljs-built_in">$C</span>(<span class="hljs-number">9</span>),company
 }

}

</div>

今後の内容..

ObjectScript とEmbedded Python と数行のコードを使用して、いつも使用する求人サイトのデータをスクレイピングし、求人タイトル、会社、給料、職務内容、メールアドレス/リンクを簡単に収集できます。

たとえば、ページが複数ある場合、ページを使用して簡単にそれらをトラバースできます。 このデータを Pandas データフレームに追加して重複を削除したら、関心のある特定のキーワードに基づいてフィルターを適用できます。 このデータを NumPy で実行してラインチャートを取得します。 または、One-Hot エンコーディングをデータに実行し、ML モデルを作成/トレーニングします。興味のある特定の求人情報がある場合は、自分に通知を送信するようにします。 😉

それではコーディングをお楽しみください!!!

「いいね」ボタンも忘れずに押してください 😃

0
0 431
記事 Toshihiko Minamoto · 5月 18, 2023 9m read

請求、支払いや領収、アイテムの配送や在庫を処理するアプリケーションでは、バーコードや QR コードの使用が必要となるのが一般的です。 単純なバーコードよりも多くの情報を格納できる QR コードは、さらに幅広いシナリオで使用されています。 したがって、バーコードと QR コードを生成する機能、またはそれらに格納されたデータを画像または PDF から読み取る機能が重要となります。 この記事では、Python と無料のライブラリを使用してこれを行う方法を説明します。

Pyzbar ライブラリ

pyzbar ライブラリは、zbar ライブラリを使って、Python 2 と 3 から 1 次元バーコードと QR コードを読み取ります。 以下の特徴が備わっています。

  • 純粋な Python。
  • PIL / Pillow 画像、OpenCV / ImageIO / NumPy ndarray、および raw バイトで動作。
  • バーコードの場所をデコード。
  • zbar ライブラリ以外の依存関係なし。
  • Python 2.7、Python 3.5~3.10 で検証済み。
詳細: https://github.com/NaturalHistoryMuseum/pyzbar/

Zbar ライブラリ

ZBar Bar Code Reader は、動画ストリーム、画像ファイル、および未加工の強度センサといった様々なソースからバーコードを読み取るためのオープンソースのソフトウェアスイートです。 EAN-13/UPC-A、UPC-E、EAN-8、Code 128、Code 93、Code 39、Codabar、ITF コード、および QR コードがサポートされています。 これらは、ライブラリの Python バインディングです。

詳細: https://sourceforge.net/p/zbar/code/ci/default/tree/python/

Python-barcode ライブラリ

Python-barcode は、Python で簡単にバーコードを作成する方法を提供しています。 SVG ファイルの生成時に、外部依存関係はありません。 画像(PNG など)の生成には Pillow が必要です。 Python 3.7~3.10 をサポートしています。

詳細: https://github.com/WhyNotHugo/python-barcode

Pillow ライブラリ

Python Imaging Library(Pillow)は、Python インタープリターに画像処理機能を追加します。 このライブラリは、広範なファイル形式のサポート、有効な内部表現、および強力な画像処理機能を提供します。 コアイメージライブラリは、いくつかの基本的なピクセル形式で格納されたデータに素早くアクセスできるように設計されています。 一般的な画像処理ツールに強固な基盤を提供します。

詳細: https://pillow.readthedocs.io/en/stable/

Opencv-Python ライブラリ

これは、OpenCV(Open Source Computer Vision Library)用の Python のラッパーで、 オープンソースのコンピュータービジョンおよび機械学習ソフトウェアライブラリです。 OpenCV は、コンピュータービジョンアプリケーションに共通のインフラストラクチャを提供し、商用製品での機械認識用途を高速化するために構築されました。 OpenCV は Apache 2 ライセンス製品であるため、コードを簡単に使用したり変更したりすることができます。

Pypdfium2 ライブラリ

これは、PDF の作成、検査、操作、およびレンダリングに使用できる PDFium という強力なリベラルライセンスライブラリへの ABI レベル Python 3 バインディングです。 ctypesgen と外部 PDFium バイナリを使用して構築されています。 そのカスタムセットアップインフラストラクチャにより、シームレスなパッケージングとインストールプロセスが提供されています。 wheel パッケージによって、広範なプラットフォームと Python バージョンがサポートされています。 一般的なユースケースを単純化するヘルパークラスが含まれていますが、未加工の PDFium/ctypes API にもアクセス可能です。

詳細: https://pypdfium2.readthedocs.io/en/stable/

サンプルアプリケーション

これらの Python ライブラリを使用して、バーコードと QR コードを生成し、画像と PDF からそれらを読み取るサンプルアプリケーションを使用できます。
以下の手順を実行してください。

  1. リポジトリを任意のローカルディレクトリに Clone/git pull します。
$ git clone https://github.com/yurimarx/iris-qr-barcode-utils.git
  1. このディレクトリで Docker ターミナルを開き、以下を実行します。
$ docker-compose build
  1. IRIS コンテナを実行します。
$ docker-compose up -d
  1. Postman(または別の REST クライアント)を使用して、バーコードを値に書き込みます。
追記: 必要に応じて、Postman サンプルリクエストを https://github.com/yurimarx/iris-qr-barcode-utils/raw/main/barcode.postman_collection.json からインポートできます。

 

Postman を使用して、QR コードを画像に書き込む

バーコードを書き込む

 

Postman を使用してバーコード値を読み取る(EAN 128 を試してください - このプロジェクトのサンプルは project-folder/code128.png です)

バーコードを読み取る

Postman を使用して PDF からバーコード値を読み取る(バーコードと QR コード付きの PDF を試してください - プロジェクトのサンプルは project-folder/product.pdf です)

PDF バーコードを読み取る

バーコードを生成するソースコード

/iris-qrbarcode/writeqrbarcodetoimage/ API でバーコードを生成するために、python-barcode ライブラリを使用しました。 このライブラリは、以下のバーコード規格をサポートしています。

  • code 39
  • code 128
  • PZN7(別名 PZN)
  • EAN-13
  • EAN-8
  • JAN
  • ISBN-13
  • ISBN-10
  • ISSN
  • UPC-A
  • EAN14
  • GS1-128

dc.qrbarcode.QRBarcodeService クラスの WriteBarcodeToImage クラスメソッドには、python-barcode を使用して EAN13 規格(13 桁の数値)のバーコードを生成する例があります。

ClassMethod WriteBarcodeToImage(number, filename) [ Language = python ]
{
    from barcode import EAN13
    from barcode.writer import ImageWriter
    import base64
 
    my_code = EAN13(number, writer=ImageWriter())
    image = my_code.save(filename)
    return image
}

最初のステップは、目的のタイプ(EAN13)に対応するクラスをコードスニペットからインポートすることです。

from barcode import EAN13

その後にクラスコンストラクターを呼び出し、生成する数値と ImageWriter を渡します。

my_code = EAN13(number, writer=ImageWriter())

画像からバーコードを読み取るソースコード

バーコードと QR コードを読み取るために、pyzbar ライブラリを使用しています。 このライブラリは、EAN/UPC、Code 128、Code 39、ITF、および QR コードをサポートしています。 dc.qrbarcode.QRBarcodeService クラスの ReadQRBarcodeFromImage クラスメソッドには、pyzbar を使ってバーコードまたは QR コードを読み取る例があります。

ClassMethod ReadQRBarcodeFromImage(image) [ Language = python ]
{
    import cv2
    from pyzbar.pyzbar import decode
    import json
 
    # Make one method to decode the barcode
    class IrisBarcode:
        def __init__(self, bardata, bartype):
            self.bardata = bardata
            self.bartype = bartype
        
    
    result = []
 
    # read the image in numpy array using cv2
    img = cv2.imread(image)
 
    # Decode the barcode image
    detectedBarcodes = decode(img)
 
    # If not detected then print the message
    if detectedBarcodes:
        for barcodeitem in detectedBarcodes:
            item = IrisBarcode(barcodeitem.data.decode("utf-8"), barcodeitem.type)
            result.append(item)
 
    return json.dumps(result, default=vars)
}

OpenCV(クラス cv2)が、画像を NumPy 配列に変換するために使用されています。 これにより、pyzbar のデコードメソッドで、この配列を読み取り、バーコードを検出することができます。 検出されたバーコードは、バーコードのタイプとデータを含む JSON で返されます。

PDF からバーコードを読み取るソースコード

最初に使用したライブラリは pypdfium2 です。 これは、PDF の各ページを画像に変換してから、pyzbar で、画像に変換された PDF ページのバーコードを読み取るために使用されています。 dc.qrbarcode.QRBarcodeService クラスの ReadQRBarcodeFromPDF クラスメソッドには、pyzbar を使って PDF ファイルからバーコードまたは QR コードを読み取る例があります。
 

ClassMethod ReadQRBarcodeFromPDF(pdfpath) [ Language = python ]
{
    from pyzbar.pyzbar import decode
    import pypdfium2 as pdfium
    import json
 
    class IrisBarcode:
        def __init__(self, bardata, bartype):
            self.bardata = bardata
            self.bartype = bartype
        
    
    pdf = pdfium.PdfDocument(pdfpath)
    result = []
    pages = len(pdf)
    
    for currentPage in range(pages):
            
        page = pdf.get_page(currentPage)
        pil_image = page.render_to(
            pdfium.BitmapConv.pil_image,
        )
 
        # Decode the barcode image
        detectedBarcodes = decode(pil_image)
 
        # If not detected then print the message
        if detectedBarcodes:
            for barcodeitem in detectedBarcodes:
                item = IrisBarcode(barcodeitem.data.decode("utf-8"), barcodeitem.type)
                result.append(item)
 
    return json.dumps(result, default=vars)
}

pdfium.PdfDocument クラスは、PDF を 1 ページずつ読み取って、Pillow 形式の個別の画像に変換するために使用されています。 次に、pyzbar のデコードメソッドによって、Pillow 表現の画像に含まれるバーコードが検出されています。 最後に、検出されたバーコードと QR コードが JSON 形式で返されます。

ボーナスコンテンツ

QR コードを生成する場合は、qrcode-library(https://pypi.org/project/qrcode/)を使用できます。 以下の例を確認してください。

import qrcode
img = qrcode.make('Some data here')
type(img)  # qrcode.image.pil.PilImage
img.save("some_file.png")

まとめ

組み込み Python を使用すると、REST API の形態であっても、相互運用性本番環境であっても、あらゆるシナリオにおいて IRIS アプリケーションでバーコードと QR コードを簡単に読み取ることができます。 Python でプロシージャを作成し、テーブルからバーコードにデータを変更することも可能です。 IRIS Analytics ダッシュボードの用途も含め、可能性はたくさんありますので、 ぜひ試してみてください!

0
0 1666
記事 Toshihiko Minamoto · 5月 11, 2023 10m read

はじめに

データ分析は、急速に展開するこの時代において、ビジネス上の意思決定を行う上で欠かせない側面です。 組織はデータ分析に大きく依存して、十分な情報に基づく意思決定と競合優位の維持を行っています。 この記事では、Pandas と InterSystems Embedded Python を使ってデータ分析を実行する方法について説明します。 Pandas の基本、InterSystems Embedded Python を使用するメリット、および両方を組み合わせて有効なデータ分析を実行する方法について説明します。

Pandas とは?

Pandas は幅広いタスクに使用可能で、Pandas ができることよりも、できないことを記述する方が簡単なくらい汎用性の高いツールです。

基本的に、Pandas はデータの拠点として機能します。 データのクリーニング、変換、分析を行うことで、データを理解しやすくすることができます。 たとえば、データセットがコンピューターに CSV ファイルとして保存されている場合、Pandas はデータを DataFrame というテーブルのような構造に抽出することができます。 この DataFrame を使用すると、以下のような様々なタスクを実行できます。

  • 各列の平均、中央値、最大値、または最小値を求める、列間の相関性の有無を判定する、特定の列のデータの分布を調べるなど、データに関して、統計を計算し、質問に答えます。
  • 欠損値の削除や特定の基準に基づく行と列のフィルタ処理によって、データをクリーニングします。
  • 棒、線、ヒストグラム、バブルなどをプロットできる Matplotlib を使ってデータを可視化します。
  • クリーニングと変換を終えたデータを CSV、データベース、または別の種類のファイルに保存します。

モデリングや複雑な可視化を詳しく見る前に、データセットの性質をしっかり理解しておくことが必要です。Pandas には、この理解を達成するために最適な方法が備わっています。

InterSystems Embedded Python を使用するメリット

InterSystems Embedded Python は、InterSystems データプラットフォーム内に組み込まれている Python ランタイム環境です。 プラットフォーム環境から離れることなく、データプラットフォーム内で Python コードを安全かつ効率的に実行する方法を提供します。 つまり、様々な環境を切り替えながらデータ分析タスクを実行する必要がないため、データ分析の効率と生産性が向上します。

Pandas と InterSystems Embedded Python の組み合わせ

Pandas と InterSystems Embedded Python を組み合わせることで、データアナリストはデータ分析タスクを簡単に実行できます。 InterSystems Embedded Python には、Python コードを実行するための安全で効率的なランタイム環境が備わっており、Pandas には、一連の強力なデータ操作ツールが備わっています。 これらを合わせることで、組織に包括的なデータ分析ソリューションを提供しています。

Pandas のインストール

Python パッケージをインストールする

Pandas と InterSystems Embedded Python と使用するには、Python パッケージとして Pandas をインストールする必要があります。 以下は、Pandas のインストール手順です。

  • 管理者モードでコマンドプロンプトを開きます(Windows)。
  • コマンドプロンプトで <installdir>/bin ディレクトリに移動します。
  • 次のコマンドを実行して Pandas をインストールします: irispip install --target <installdir>\mgr\python pandas 。このコマンドによって Pandas は InterSystems が推奨する <installdir>/mgr/python ディレクトリにインストールされます。インストールするパッケージによって、実際のコマンドは異なる場合があります。 pandas を、インストールしたいパッケージの名前に置き換えてください。

それだけです! これで、Pandas と InterSystems Embedded Python を使用できるようになりました。

 irispip install --target C:\InterSystems\IRIS\mgr\python pandas

Pandas をインストールしたので、employees データセットで作業できるようになりました。 以下は、CSV ファイルを Pandas DataFrame に読み込み、データクリーニングと分析を実行する手順です。

まず、Python の新しいインスタンスを作成しましょう

Set python = ##class(%SYS.Python).%New()

Python ライブラリをインストールします。ここでは、pandas と buildins をインポートします。

Set pd = python.Import("pandas")

#;To import the built-in functions that are part of the standard Python librarySet builtins = python.Import("builtins")

データを pandas ライブラリにインポート

InterSystems Embedded Python を使用して Pandas DataFrame にデータを読み込むには、いくつかの方法があります。 以下は一般的な 3 つの方法です。
次のサンプルファイルをとして使用しています。

CSV からデータを読み取る

CSV ファイルへのパスを使って read_csv() を使用し、カンマ区切り値を読み取ります。

Set df = pd."read_csv"("C:\InterSystems\employees.csv")

テキストファイルをインポートする {#importing-text-files}

テキストファイルの読み取りは CSV ファイルに似ています。 唯一のニュアンスは、以下に示すように、sep 引数で区切り文字を指定する必要があることです。 この区切り文字引数は、DataFrame 内の行を区切るために使用するシンボルを参照します。 区切り文字として、コンマ(sep = ",")、ホワイトスペース(sep = "\s")、タブ(sep = "\t")、コロン(sep = ":")が一般的に使用されます。 ここでは、\s は 1 つのホワイトスペース文字を表します。

Set df = pd."read_csv"("employees.txt",{"sep":"\s"})

Excel ファイルのインポート

単一シートの Excel ファイルをインポートするには、ファイルパスを入力とする "read_excel()" 関数を使用します。 たとえば、df = pd.read_excel('employees.xlsx') というコードの場合、"diabetes.xlsx" という Excel ファイルを読み取り、そのコンテンツを "df" という DataFrame に格納します。

どの行を DataFrame のヘッダーにするかを決定するヘッダー引数など、他の引数も指定することができます。 デフォルトでは、ヘッダーは 0 に設定されているため、最初の行がヘッダーまたは列名になります。 列名を指定する場合は、names 引数に名前のリストを渡すことができます。 ファイルに行インデックスが含まれる場合は、index_col 引数を使って指定できます。

Pandas DataFrame または Series では、インデックスが行または列の位置を指す識別子であることに注意してください。 DataFrame の行または列にラベルを付け、インデックスを使用して特定の行または列にアクセスすることができます。 行インデックスは、値の範囲、時系列、一意の識別子(社員 ID など)、またはその他の種類のデータにすることができます。 列に関しては、インデックスは通常、列名を示す文字列です。

Set df = pd."read_excel"("employees.xlsx")

Excel ファイルをインポートする(複数のシート){#importing-excel-files-(multiple-sheets)}

複数のシートが含まれる Excel の読み取りも、それほど変わりません。 sheet_name という追加の引数を 1 つ指定し、シート名の文字列またはシート位置の整数を渡すだけです(Python では 0 インデックスが使用されているため、最初のシートは sheet_name = 0 でアクセスできます)。

#; Extracting the second sheet since Python uses 0-indexingSet df = pd."read_excel"("employee.xlsx", {"sheet_name":"1"})

JSON からデータを読み取る

Set df = pd."read_json"("employees.json")

DataFrame 内のデータを確認

.head().tail() を使ってデータを表示する方法

これには、インポートした builtins ライブラリを使用できます(ZW でも動作しますwink

do builtins.print(df.head())

データセットの列をすべて表示

Do builtins.print(df.columns)

データのクリア

'Start Date' 列を日時オブジェクトに変換

Set  df."Start Date" = pd."to_datetime"(df."Start Date")

更新後のデータセットは以下のようになります。

'Last Login Time' 列を日時オブジェクトに変換

Set df."Last Login Time" = pd."to_datetime"(df."Last Login Time")

'Salary' 列の欠損値に平均給与を設定

Set meanSal = df."Salary".mean()
Set df."Salary" = df."Salary".fillna(meanSal)

 

分析の実行

性別ごとの平均給与を計算

Do builtins.print(df.groupby("Gender")."Salary".mean())

チームごとの平均ボーナス率を計算

Do builtins.print(df.groupby("Team")."Bonus %".mean())

 

毎年採用される社員数を計算

Do builtins.print(df."Start Date".dt.year."value_counts"()."sort_index"())

 

年功者かどうかで社員数を計算

Do builtins.print(df."Senior Management"."value_counts"())

Pandas でのデータの出力 {#outputting-data-in-pandas}

Pandas は様々なファイルタイプからデータをインポートできるように、様々な形式にエクスポートすることも可能です。 これは特に、データが Pandas を使って変換され、ローカルマシン上に保存する必要がある場合に行われます。 以下は、Pandas DataFrams を様々な形式で出力する方法です。

DataFrame を CSV ファイルに出力する {#outputting-a-dataframe-into-a-csv-file}

Pnadas DataFrame(ここでは df を使用)は、."to_csv"() メソッドを使って CSV ファイルとして保存されます。 

do df."to_csv"("C:\Intersystems\employees_out.csv")

 

DataFrame を JSON ファイルに出力する {#outputting-a-dataframe-into-a-json-file}

."to_json"() メソッドを呼び出して、DataFrame オブジェクトを JSON ファイルにエクスポートします。

do df."to_json"("C:\Intersystems\employees_out.json")

 

DataFrame を Excel ファイルに出力する {#outputting-a-dataframe-into-an-excel-file}

DataFrame オブジェクトから ."to_excel"() を呼び出して、“.xls” または “.xlsx” ファイルとして保存します。

do df."to_excel"("C:\Intersystems\employees_out.xlsx")

 

毎年採用される社員数を示す基本的な棒グラフを作成してみましょう。

これには、matplotlib.pyplot を使用します。
 

//import matplotlibSet plt = python.Import("matplotlib.pyplot")
//create a new dataframe to reprecent the bar chartset df2 = df."Start Date".dt.year."value_counts"()."sort_index"().plot.bar()
//export the output to a pngdo plt.savefig("C:\Intersystems\barchart.png")
//cleanupdo plt.close()

以上です! これらの単純なステップを使えば、CSV ファイルを読み取り、データをクリーニングして、InterSystems Embedded Python で Pandas を使って、基本的な分析を実行できます。

動画

以下のリンクを使って、動画にアクセスできるようになりました。 動画そのものは、上記のチュートリアルの包括的な概要と詳細として機能します。
https://youtu.be/hbRQszxDTWU

まとめ 

提供されたチュートリアルは、Pandas が実行できる基本機能しかカバーされていません。 Pandas を使うと、広範なデータ分析、可視化、フィルタリング、集計タスクを実行できるため、あらゆるデータワークフローで貴重なツールとなります。 また、他のデータサイエンスパッケージと組み合わせると、たとえば、対話型ダッシュボードを構築し、機械学習モデルを開発して予測を行い、データワークフローを自動化することができます。 Pandas の理解をさらに深めるには、以下に記載するリソースを調べ、学習過程を加速させましょう。

免責事項

Pandas と InterSystems の活用には様々な方法があることに注意してください。 提供された記事は、教育のみを目的としており、最も最適なアプローチを保証するものではありません。 この記事の著者として、Pandas の機能を継続的に学習し調査しているため、より良い結果を生み出す別の方法や手法が存在する可能性があります。 したがって、読者は慎重な判断と注意を以って、この記事に記載さあれている情報を各自のプロジェクトに適用することをお勧めします。

0
0 335
記事 Mihoko Iijima · 2月 24, 2023 4m read

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

InterSystems デベロッパーツールコンテスト2023 の21の応募作品の中から、Experts Nomination 第4位に輝いた @Muhammad Waseem さんのiris-geo-map(インタラクティブに地図を生成し、地理データを視覚化するツール)についてご紹介します。

このツールは、Embedded Pythonを利用していて Folium Python ライブラリを使用されています。

特徴については @Muhammad Waseem さんの Open Exchange のREADMEもぜひご参照ください。

それでは、さっそく、使用開始までの手順です。(とても簡単です)

IPM(InterSystems Package Mangaer:以前はZPMとも呼ばれていました)のクライアントツールを管理ポータルかスタジオからインポートしたら、以下コマンドを実行するだけでツールの準備が整います。

クライアントツールのインポートはどのネームスペースでも大丈夫です。管理ポータルからインポートされる場合は、以下メニューを利用します。

管理ポータル→システムエクスプローラ→クラス→インポート対象ネームスペースを選択→インポートボタンクリック

ツールを配置したいネームスペースに移動し、ZPMコマンドを利用してインストールします。

0
0 299
記事 Toshihiko Minamoto · 1月 16, 2023 7m read

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

InterSystems IRIS で embedded python を使用する一般的なプロジェクトの出発点として推奨できる、最小限の embedded python テンプレート をご紹介しましょう。

特徴:

  • Embedded python対応
  • Embedded Pythonの3つの開発方法の例
  • VSCode開発対応
  • Dockerが利用可能
  • オンラインデモが可能
  • ZPM First開発対応。

以下、その特徴について説明しましょう。

まず、Embedded Pythonについて説明します。この機能は InterSystems IRIS 2021.2 に搭載されており、InterSystems IRIS と python を使用したソリューションを開発することができます。 IRIS 2021.2以降では、InterSystems IRISとの共有メモリ環境でpythonスクリプトを実行でき、python開発者は、コードがデータに近いデータベースを使用する際に、独自のオプションを得ることができます。 

Embedded Pythonによる3つの開発モード

ObjectScript から python のライブラリをコールする

これは、%SYS.Pythonクラスにより、Pythonのライブラリをインポートし、ObjectScirptを介してPythonをコールすることができるようになったからです。 ドキュメント, . 以下のコードを参照してください。

ClassMethod Today() As%Status
{
  Set sc = $$$OKSet dt = ##class(%SYS.Python).Import("datetime")
  write dt.date.today().isoformat()
  Return sc
}

Python で ObjectScript クラスメソッドを記述する

実際、開発者はメソッドのシグネチャに [Language=python] タグを付けて、pure python でコーディングできるようになった。また、ObjectScriptのクラスやグローバルを参照するためのヘルパーpythonライブラリ "iris"も用意されています。 ドキュメント、以下のサンプルコード

ClassMethod CreateRecordPython(propValue As %VarString, ByRef id As %Integer) [ Language = python ]
{
    import iris
    obj=iris.cls(__name__)._New()
    obj.Test=propValue
    sc=obj._Save()
    id=obj._Id()
    return sc
}

InterSystems IRISソリューションのpure pythonでのコーディング

これは、開発者がIRISを扱う方法の3番目のオプションです。  ここでは、pythonスクリプトをIRISに接続する必要があり、これはENV変数とCallInサービスの "On "を介して行うことができます(詳細は以下を参照)。一度セットアップされたPythonスクリプトは、IRISとの共有メモリで実行されます。ここで、"iris" ライブラリが非常に役に立ちます。 ドキュメント,

defcreate_rec(var):
    obj=iris.cls('dc.python.PersistentClass')._New()
    obj.Test=var
    obj._Save()
    id=obj._Id()
    return id

# テストレコード作成from datetime import datetime
now=str(datetime.now())
print("dc.python.PersistentClass で新しいレコードを作成する")
print(create_rec(now))

## SQLを実行し、データをプリントするdefrun_sql(query):
    rs=iris.sql.exec(query)
    for idx, row in enumerate(rs):
        print(f"[{idx}]: {row}")

query="dc_python.PersistentClass から * を選択する"
print("SQLクエリの実行 "+query)
run_sql(query)

Dockerが可能

テンプレートリポジトリは、コンテナ内でIRISを実行し、Embedded Pythonの調整に必要なすべてをセットアップします。

環境変数。Embedded PythonはIRISに接続してPythonスクリプトを実行するために、特定の環境変数の設定を必要とします。以下は、それを助ける設定をdockerfileに記述しています:

# init Python env
ENV PYTHON_PATH=/usr/irissys/bin/irispython
ENV SRC_PATH=/irisrun/repo
ENV IRISUSERNAME "SuperUser"
ENV IRISPASSWORD "SYS"
ENV IRISNAMESPACE "USER"

また、Embedded Python は CallIn サービスを "ON" にする必要があり、これは docker build フェーズで iris.script で行われます。

; Embedded Pythonのcallinを可能do##class(Security.Services).Get("%Service_CallIn",.prop)
    set prop("Enabled")=1set prop("AutheEnabled")=48do##class(Security.Services).Modify("%Service_CallIn",.prop)

また、あなたのソリューションには、いくつかの Python ライブラリのインストールが必要かもしれません。これは、リポジトリのルートにある requirements.txtdockerfileにある pip3 コールによって提供されます:

pip3 install -r requirements.txt && \

VSCode開発対応

VSCodeでdockerを使って開発するのはとても便利です。Embedded pythonのVSCodeを使ったIRISソリューションをdockerで開発する場合、Devcontainer modeに切り替える必要があります。 .devcontainer フォルダに devcontainer.json ファイル を導入してください。これは、どのDockerサービスと連携する必要があるかを記述しており(私たちのケースではirisです)。コンテナ内で動作しているIRISが使用するPythonエンジンが提供するVSCode内のPythonスクリプトを実行するのに役立ちます。 devcontainer.json ファイルには、コンテナモードでどの extensions を使用する必要があるのかを記述したセクションもあります。

"extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "intersystems-community.vscode-objectscript",
        "intersystems.language-server",
        "intersystems-community.servermanager",
        "ms-vscode.docker"
    ],

ZPMを使用したEmbedded Pythonソリューションのインストール

このテンプレートは、「ZPM first」開発リポジトリとして設定されています。つまり、開発したコードはすべて module.xml に記述され、Docker イメージをビルドするたびに ZPM モジュールとしてインストールされます。つまり、開発者は毎回 iris.script の 次の行 からコーディングを開始します:

zpm "load /home/irisowner/irisbuild/ -v":1:1

そして、Embedded pythonのコードもZPMモジュールに記述され、FILECOPYを介してインストールされます:

この式は、リポジトリ内の /python フォルダにあるすべての python スクリプトをパッケージ化し、ターゲット IRIS インストールの libdir 内の python/ フォルダにインストールしたいことを意味します。python スクリプトが ${libdir}python/ フォルダにコピーされると、ターゲット IRIS マシンの ObjectScirpt または Python からのインポート コールに利用できるようになります。

注意:他のPythonコードを誤って上書きしないように、Pythonスクリプトのフォルダ名称は、ユニークなものにしてください。

このテンプレートがあなたのお役に立つことを願っています。フィードバック、特にプルリクエストは大歓迎です。

0
0 215
記事 Toshihiko Minamoto · 12月 21, 2022 7m read

Django の可能性と IRIS の使用方法を引き続き観察しています。 初めにモデルの定義方法と、IRIS に存在しているテーブルへの接続方法を確認し、次に組み込みの Django 管理ポータルを拡張して、モデルに含まれるデータの表示、フィルタ、編集、そしてページネーションの機能を追加しました。

では、実際の動作を確認しましょう。posts-and-tags パッケージで使用したデータで Django に REST API を作成します。

それには、Django REST Framework を使用します。

Django REST Framework

Django REST Framework は、Web API を構築するための強力で柔軟性を備えたツールキットです。

REST Framework の使用を推奨するのには、以下のような理由があります。

  • Web で閲覧可能な API には、開発者のユーザビリティにおいて大きなメリットがあります。
  • OAuth1a と OAuth2 の認証ポリシーを含むパッケージ
  • ORM と非 ORM データソースの両方をサポートするシリアル化
  • すべてをカスタマイズ可能。強力な機能が必要なければ、通常の関数ベースのビューを使用できます。
  • 詳細なドキュメントと優れたコミュニティサポート
  • Mozilla、Red Hat、Heroku、Eventbrite など、世界的に有名な企業が使用・信頼
まず、依存関係で requirements.txt を更新する必要があります。
# Django そのもの
django>=4.0.0 

# Django 用 InterSystems IRIS ドライバー、InterSystems の DB-API ドライバー
django-iris=>0.1.13
https://raw.githubusercontent.com/intersystems-community/iris-driver-distribution/main/DB-API/intersystems_irispython-3.2.0-py3-none-any.whl 

# Django REST Framework とそのオプションの依存関係
djangorestframework>=3.4.4
# 閲覧可能な API の Markdown サポート
markdown>=3.0.0 
# フィルタサポート
django-filter>=1.0.1

そして、これらをインストールします。

python install -r requirements.txt

API の初稿

urls.py ファイルを以下に更新します。 ここでは、API のルートを api/ に更新し、API リクエストに対し、http://localhost:8000/api/ がルートとして使用されるようにします。

from django.contrib import admin
from django.urls import path, include
from rest_framework import routers

router = routers.DefaultRouter()

urlpatterns = [
    path('api/', include(router.urls)),
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls')),
]

Django REST Framework には、settings.py の DEBUG=True によりサーバーが開発モードで実行している場合、API の UI が組み込まれています。 この URL を開きましょう。

何も定義されておらず、フレームワークが URL に接続されているだけでも、すべてが機能しています。 認証を必要とするリクエストに対しては、認証がサポートされています。 

$ curl http://127.0.0.1:8000/api/
{}

プロジェクトの API を定義しましょう。最低限、REST Framework のいくつかの機能を使用します。

  • シリアライザー - クエリセットやモデルインスタンスなどの複雑なデータをネイティブ Python データ型に変換し、JSONXML などのコンテンツタイプに簡単にレンダリングできるようにします。 シリアライザーは逆シリアル化も提供しているため、着信データを検証してから、解析したデータを複雑な型に変換し直すことも可能です。
  • ビューセット - 関連する一連のビューのロジックを 1 つのクラスにまとめることができます。

Post 用のエンドポイントを追加しましょう。 とてもシンプルではありますが、 更新された _urls.py _ のコンテンツを見てみましょう。

from django.contrib import admin
from django.urls import path, include
from rest_framework import routers, serializers, viewsets
from .models import CommunityPost

router = routers.DefaultRouter()

class CommunityPostSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        # class with model
        model = CommunityPost
        # list of fields to show, or just '__all__'
        fields = '__all__'
# ViewSets define the view behavior.
class CommunityPostViewSet(viewsets.ModelViewSet):
    queryset = CommunityPost.objects.all()
    serializer_class = CommunityPostSerializer

# connect it with API
router.register(r'posts', CommunityPostViewSet)

urlpatterns = [
    path('api/', include(router.urls)),
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls')),
]

これで Web UI に表示されるようになりました。

ここのリンクをクリックすると、そのレスポンスを確認できます。

最後までスクロールすると、新しい項目用に生成されたフォームがあります。これは POST リクエストで追加可能です。 すべてのフィールドがプロパティの型に適しています。

項目リストで任意の項目の URL をクリックして、これを確認します。 レスポンスのこの項目と、PUT リクエストを使った編集フォームのみです。

認証

PUT か POST でデータを変更できるようになりました。 認証の要件はまだ有効化されていません。 REST Framework には、使用できる認証の組み合わせが様々用意されているため、匿名アクセスの読み取り専用リソースを一部開放することができます。 そして、変更を行うための認証を行います。 または、アクセスを完全に閉鎖することも可能です。 ここでは、匿名の読み取り専用に構成し、変更には認証を必要とするようにしましょう。 それには、次のコードを settings.py に追加すれば完了です。

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',
    ],
}

これを使用すれば、Django 管理用に前に作成したユーザー名とパスワードなどでログインするまで、フォームが表示されなくなります。

ページネーション

デフォルトではページネーションはありませんが、リストクエリに簡単に追加できます。 settings.pyREST_FRAMEWORK 変数を更新しましょう。 ページネーションクラスとデフォルトのページサイズをセットアップします。

REST_FRAMEWORK = {
...
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
    'PAGE_SIZE': 10,
...
}

これにより、生成される JSON がわずかに変わりました。「次へ」や「前へ」といったページリンクや全項目数などの関連する項目が追加されています。 これで、Web UI でページを移動できるようになりました。

フィルタと検索

フィルタ機能と検索機能の追加も非常に単純です。 settings.pyREST_FRAMEWORK 変数を更新しましょう。 

REST_FRAMEWORK = {
... 
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        'rest_framework.filters.SearchFilter',
    ],
...
]

そして、CommunityPostViewSet をフィルタと検索用のフィールドのリストで更新します。

class CommunityPostViewSet(viewsets.ModelViewSet):
    queryset = CommunityPost.objects.all()
    serializer_class = CommunityPostSerializer
    filterset_fields = ['posttype', 'lang', 'published']
    search_fields = ['name',]

これで、Web UI で動作するようになりました。

最後に、完全に機能する REST API が完成しましたが、今のところ、このリソース専用の API です。 非常に単純ですが、十分にカスタマイズ可能で、他のリソースに接続したり、リンクしたリすることが可能です。

0
0 303
お知らせ Mihoko Iijima · 11月 10, 2022

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

開発者コミュニティのYouTubeプレイリストにEmbedded Pythonの新しいセルフラーニングビデオを公開しましたのでお知らせします📣!

◆ Embedded Pythonでデータベースプログラミング:オブジェクトアクセス編

※YouTubeに移動していただくとプレイリストの中から好きなビデオを選択してご覧いただけます。

0
0 142
お知らせ Mihoko Iijima · 11月 7, 2022

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

開発者コミュニティのYouTubeプレイリストに新しいセルフラーニングビデオを公開しましたのでお知らせします📣!

◆ IRISでPythonを使ってみよう!

※YouTubeに移動していただくとプレイリストの中から好きなビデオを選択してご覧いただけます。

0
0 238
記事 Toshihiko Minamoto · 10月 25, 2022 8m read

私が一番興味を持っているのは、組み込み Python におけるグローバルの使用についてです。
そこで、提供されている公式ドキュメントを確認しました。

#1 グローバルの導入
グローバルとは何かについての一般的な説明。 次の章につながっています。

#2 ObjectScript の詳細について
組み込み Python の記述はありません。
さらに先に進むと...

#3 組み込み Python

3.1 組み込み Python の概要
3.1.1 グローバルの使用

グローバルを使ったことなければ、素晴らしい内容です。
が、驚くほど原始的な例が使われています。
3.2 組み込み Python の使用
最後の望み: >>> でも、目に見えるものが何もありません
残念どころではありません! Python 用の IRIS Native API でさえ、もっと説明されています。
何を期待していたかと言うと...

グローバルノードの SET、GET、KILL

Native API: 基本的なノード操作  そして

$DATA()、$ORDER()、$QUERY() によるナビゲーション

Native API: nextSubscript() と isDefined() によるイテレーション
そこで、自分で調査し、リバースエンジニアリングを行って、実験しなければなりませんでした。

そしてわかったこと:

すべての例は IRIS for Windows (x86-64) 2022.1 (Build 209U) にある Python Shell で説明されており、
暗黙的な print() 関数を集中的に使用している。

グローバル

何をするにも、iris.gref クラスを使って、グローバルの参照オブジェクトを作成することから始める必要があります。
グローバル名は、直接文字列として、またはCOS/ISOS の間接式のように変数として渡されます。
グローバルを扱っていることが明確であるため、最初のキャレット (^) は不要です!

>>> globalname='rcc'
   >>> nglob=iris.gref(globalname)
   >>> glob=iris.gref('rcc')
   >>> cglob=iris.gref('^rcc')
上記は、同じグローバルへの 3 つのグローバル参照です。
単なる参照であり、このグローバルが存在するかことを示すものではありません。
対話式ドキュメント:  print(glob.__doc__)
InterSystems IRIS グローバル参照オブジェクト。
グローバルへの参照を取得するには、iris.gref() メソッドを使用します。
 
サブスクリプト

すべてのグローバルサブスクリプトは、Py リストの [sub1,sub2] として渡されます。 COS/ISOS とあまり変わりません。
トップレベルに特別な処理が必要なだけです。
サブスクリプトなしを示すには、空のリストではなく、この [None] を使用します。

SET

グローバルを設定するには、COS/ISOS と同様に「直接」行うことができます。

>>> glob[1,1]=11

または、gref.set() メソッドを使用することもできます。

>>> glob.set([1,3],13)

対話式ドキュメント:  print(glob.set.__doc__)
グローバルのキーが指定されている場合、グローバルのそのキーに格納された値を設定します。  
例: g.set([i,j], 10) は、グローバル g のキー i,j にあるノードの値を 10 に設定します。

グローバルノードのコンテンツにアクセスするには、COS/ISOS と同様に「直接」行うことができます。

>>> glob[1,3]
   13

または、gref.get() メソッドを使用することもできます。

>>> glob.get([1,1])
   11

対話式ドキュメント: print(glob.get.__doc__)
グローバルのキーが指定されている場合、グローバルのそのノードに格納された値を返します。
例: x = g.get([i,j]) は x を、グローバル g のキー i,j に格納された値に設定します。

注意: これは COS/ISOS の $GET() ではありません

>>> glob.get([1,99])
   Traceback (most recent call last):
   File "", line 1, in &lt;module>
   KeyError: 'Global Undefined'
   >>>

ただし、直接使用すると、COS/ISOS の $GET() のように動作します。

>>> x=glob[1,99]
   >>> print(x)
   None
   >>>

この None は、SQL が表現するところの NULL を指します。 後で、もう一度出現します。

KILL

期待される結果を達成する gref.kill() メソッドのみがあります。

>>> glob.kill([1,3])
   >>> y=glob[1,3]
   >>> print(y)
   None
   >>>

対話式ドキュメント: print(glob.kill.__doc__)
グローバルのキーが指定されている場合、グローバルのそのノードとサブツリーをキルします。
例: g.kill([i,j]) は、グローバル g のキー i,j に格納されたノードとその子孫ノードをキルします。

$DATA()

関連するメソッドは gref.data() です。
対話式ドキュメント: print(glob.data.__doc__)
グローバルのキーが指定されている場合、その状態を返します。
例: x = g.data([i,j]) は x を 0、1、10、11 に設定します。
0-if が未定義、1-定義済み、10-未定義で子孫あり、11-値と子孫あり
期待どおりに動作します。

>>> glob.data()
   10
   >>> glob.data([None])
   10
   >>> glob[None]=9
   >>> glob.data([None])
   11
   >>> glob.data([1,1])
   1
   >>> glob.data([1,3])
   0
   >>>

$ORDER()

この例では、グローバル ^rcc にノードをいくつか追加しました。

>zw ^rcc
   ^rcc=9
   ^rcc(1,1)=11
   ^rcc(1,2)=12
   ^rcc(2,3,4)=234
   ^rcc(2,3,5)=235
   ^rcc(2,4,4)=244
   ^rcc(7)=7

関連するメソッドは gref.order() です。
対話式ドキュメント: print(glob.order.__doc__)
グローバルのキーが指定されている場合、そのグローバルの次のキーを返します。
例: j = g.order([i,j]) は j を、グローバル g の次の第 2 レベルのキーに設定します。
つまり、以下のようになります。

>>> print(glob.order([]))
   1
   >>> print(glob.order([1]))
   2
   >>> print(glob.order([2]))
   7
   >>> print(glob.order([7]))
   None
   >>> print(glob.order([1,'']))
   1
   >>> print(glob.order([1,1]))
   2
   >>> print(glob.order([2,3,]))
   4
   >>> print(glob.order([2,3,""]))
   4
   >>> print(glob.order([2,3,4]))   
   5
   >>> print(glob.order([2,4,4]))
   None
   >>>

ここでは、参照として欠落しているサブスクリプトまたは空の文字列は同等です。

$QUERY()

関連するメソッドは gref.query() です。
対話式ドキュメント: print(glob.query.__doc__)
指定されたキーからグローバルをトラバースし、各キーと値をタプルとして返します。
例: for (key, value) in g.query([i,j]) は、キー i,j から g をトラバースし、各キーと値を返します。

このメソッドの動作は COS/ISOS と異なります。

  • 開始ノード以降のすべてのノードを返します。
  • 格納されたコンテンツを含めます。
  • None と示されているコンテンツのない仮想ノードも返します。 ここでの小さな例は、次のようになります(読みやすいように囲んでいます)。
>>> print(list(glob.query()))
   [(['1'], None), (['1', '1'], 11), (['1', '2'], 12), (['2'], None), 
        (['2', '3'], None), (['2', '3', '4'], 234), (['2', '3', '5'], 235), 
        (['2', '4'], None), (['2', '4', '4'], 244), (['7'], 7)]
   >>>

もっと読みやすくすると、次のようになります。

>>> for (key, value) in glob.query():
   ...  print(key,''.ljust(20-len(str(list(key))),'>'),value)
   ...
   ['1'] >>>>>>>>>>>>>>> None
   ['1', '1'] >>>>>>>>>> 11
   ['1', '2'] >>>>>>>>>> 12
   ['2'] >>>>>>>>>>>>>>> None
   ['2', '3'] >>>>>>>>>> None
   ['2', '3', '4'] >>>>> 234
   ['2', '3', '5'] >>>>> 235
   ['2', '4'] >>>>>>>>>> None
   ['2', '4', '4'] >>>>> 244
   ['7'] >>>>>>>>>>>>>>> 7
   >>>

絶対に ZWRITE ではありません!

もう 1 つのオプションは、gref.keys() のみを使用してサブスクリプトを取得する方法です。
対話式ドキュメント: print(glob.keys.__doc__)
指定されたキーからグローバルをトラバースし、そのグローバルの各キーを返します。
例: for key in g.keys([i, j]) は、キー i,j から g をトラバースし、各キーを返します。 >>>

>>> list(glob.keys())
   [['1'], ['1', '1'], ['1', '2'], ['2'], ['2', '3'], ['2', '3', '4'], 
                 ['2', '3', '5'], ['2', '4'], ['2', '4', '4'], ['7']]
   >>>

そして、これで gref.orderiter() を見つけました。
対話式ドキュメント: print(glob.orderiter.__doc__)
指定されたキーからグローバルをトラバースし、次のキーと値をタプルとして返します。
例: for (key, value) in g.orderiter([i,j]) は、キー i,j から g をトラバースし、次のキーと値を返します。

$QUERY() のようにコンテンツをフェッチして、
そのコンテンツを次のサブノードに提供することも行う $ORDER() のように動作します。
以下を見てください。

>>> list(glob.orderiter([]))
   [(['1'], None), (['1', '1'], 11)]
   >>> list(glob.orderiter([1]))
   [(['2'], None), (['2', '3'], None), (['2', '3', '4'], 234)]
   >>> list(glob.orderiter([2]))
   [(['7'], 7)]
   >>>

最後に、gref.getAsBytes() メソッドがあります。
対話式ドキュメント: print(glob.getAsBytes.__doc__)
グローバルのキーが指定されている場合、そのグローバルのそのノードに格納されている文字列をバイトで返します。
例: x = g.getAsBytes([i,j]) は x をグローバル g のキー i,j に格納されている値をバイトとして設定します。

数値には失敗しますが、 文字列には有効です。

   >>> glob[5]="robert"
   >>> glob.get([5])
   'robert'
   >>> glob.getAsBytes([5])
   b'robert'

また、COS/ISOS で set ^rcc(9)=$lB(99,"robert") を実行すると
以下のようになります。

>>> glob[9]
   '\x03\x04c\x08\x01robert'
   >>> glob.getAsBytes([9])
   b'\x03\x04c\x08\x01robert'
   >>>

これらのメソッドを以下のようにして検出しました。

>>> for meth in glob.__dir__():
   ...  meth
   ...
   '__len__'
   '__getitem__'
   '__setitem__'
   '__delitem__'
   '__new__'
   'data'
   'get'
   'set'
   'kill'
   'getAsBytes'
   'order'
   'query'
   'orderiter'
   'keys'
   '__doc__'
   '__repr__'
   '__hash__'
   '__str__'
   '__getattribute__'
   '__setattr__'
   '__delattr__'
   '__lt__'
   '__le__'
   '__eq__'
   '__ne__'
   '__gt__'
   '__ge__'
   '__init__'
   '__reduce_ex__'
   '__reduce__'
   '__subclasshook__'
   '__init_subclass__'
   '__format__'
   '__sizeof__'
   '__dir__'
   '__class__'
   >>>

これで、組み込み Python からグローバルに直接アクセスする必要がある場合に、作業が楽になることを願っています。
個人的に学んだこと: ほとんどの場合に、ドキュメントがあります。 . . . どこにあるかは別ですが。
ただ、探し回る必要があるだけです。

動画デモ

Traduction française

0
1 305
記事 Toshihiko Minamoto · 10月 5, 2022 4m read

IRIS における Python サポートの最近の改善と、InterSystems による Python DB-API サポートへの継続的な作業により、 Django プロジェクトに IRIS サポートを実装しました。Python DB-API の使用により、他のデータベースと連携することが可能です。

Django で、IRIS にデータを保存する単純なアプリケーションを試してみましょう。

ToDo アプリ

このアプリケーションは

GitHub にあります。それをクローンしましょう。

git clone https://github.com/caretdev/django-iris-todo
cd django-iris-todo

次に、Docker-compose でビルドして起動します。

docker-compose up -d --build

IRIS の起動にはしばらくかかりますが、Django アプリケーションは起動をキャッチしてそこにモデルを移行し、アプリケーションも起動します。起動が完了すると、http://localhost:8000/ で利用できるようになり、上記の図のようになります。

仕組み

動作させるには、InterSystems Python DB-API がインストールされている必要があります。最新のプレビューバージョンが含まれているため、2022.1.0.114.0 以上のバージョンが必要です。これは、インスタンスの &lt;INSTALL_DIR>/dev/python/ フォルダにあります。 このファイルは、こちらの GitHub リポジトリからダウンロードすることもできます。 

pip3 install intersystems_irispython-3.2.0-py3-none-any.whl

Django の IRIS バックエンドは別のプロジェクトで実装されており、pip を使ってインストール可能です。当然 django そのものも必要なので、それらをインストールしましょう。

pip3 install django django-iris

別の方法として、requirements.txt ファイルを使用して必要なパッケージを Python にインストールすることができます。

pip3 install -r requirements.txt

ただし、このファイルには以下の行が含まれます。

https://raw.githubusercontent.com/intersystems-community/iris-driver-distribution/main/intersystems_irispython-3.2.0-py3-none-any.whl
Django~=4.0.2
django-iris~=0.1.5

Django アプリケーションを IRIS に接続して、todoApp/settings.py ファイルを開きましょう。

DATABASES は、データベースへの接続設定を定義します。

ENGINE は django_IRIS である必要があります。

NAME は IRIS のネームスペースにポイントする必要があります。

接続できるものに変更しましょう。 たとえば、以下のようにします。

DATABASES = {
    'default': {
        'ENGINE': 'django_iris',
        'NAME': 'DJANGOTODO',
        'HOST': 'localhost',
        'PORT': 1972,
        'USER': '_SYSTEM',
        'PASSWORD': 'SYS',
    }
}

そして移行を開始します。

python3 manage.py migrate

エラーもなく、IRIS 側のすべてのテーブルが作成されました。

これで、アプリケーションを起動することができます。

python3 manage.py runserver

Django には管理者パネルがあります。

python3 manage.py createsuperuser

管理者パネルは、http://localhost:8000/admin/ で利用できます。 

IRIS にはこのように格納されています。

完全にサポートするには、ほかにもいくつかの作業が残っています。 InterSystems からの Python DB-API ドライバーはまだ開発中であり、この django-iris プロジェクトも進行中です。

Community Edition ではあまりうまく動作しない可能性があるので注意してください。これは Django がデータベースに接続する方法に起因しており、すべてのライセンスをかなり素早く消費してしまう可能性があるためです。

プロジェクトと、IRIS を使った今後のインパクトを気に入っていただけたら、OpenExchange コンテストでぜひ投票してください。

0
0 375
記事 Toshihiko Minamoto · 9月 26, 2022 8m read

プログラムによる本番環境アクセス

プログラムで本番環境(インターフェース)を編集するには、相互運用性 apis と SQL クエリを組み合わせて使用できます。

現在のネームスペース

大まかに言えば、その時点で作業しているネームスペースと本番環境を知ることが重要です。

// Object script 
// アクティブなネームスペースはこの変数に格納される
$$$NAMESPACE 
// ネームスペースを出力
Write $$$NAMESPACE
# Python
import iris
# このメソッドからアクティブなネームスペースが返される
iris.utils._OriginalNamespace()
# ネームスペースを出力
print(iris.utils._OriginalNamespace())
>>> DEMONSTRATION

現在の本番環境(アクティブまたは最後に実行した本番環境)

本番環境の名前を知ることも重要です。次の API を使用してネームスペース内のアクティブな本番環境を取得できます。

// ObjectScript
USER>ZN "DEMONSTRATION"
// 現在または最後に実行した本番環境を取得
DEMONSTRATION>W ##class(Ens.Director).GetActiveProductionName()
>>> Hospital.HospitalProduction
#  Python
import os
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
active_production = iris.cls('Ens.Director').GetActiveProductionName()
print(active_production)
>>> Hospital.HospitalProduction

本番環境内の項目を検索する

ObjectScript または Python を使用して、本番環境内のアクティブな項目を検索できます。

1. SQL クエリで本番環境内の項目を調べる

SELECT Name FROM Ens_Config.Item Where Production = 'Hospital.HospitalProduction'
-- 
['From_Athena_Multi']
['From_Athena_Multi_Router']
['From_Cerner_ADT']
['From_Cerner_ADT_Router']
['From_Cerner_Orders']
['From_Cerner_Orders_Router']
['From_Dictaphone_Results']
['From_Dictaphone_Results_Router']
['From_Lab_Results']
['From_Lab_Results_Router']
['From_Radiology_Results']
['From_Radiology_Results_Router']
['HS.IHE.XDSb.DocumentSource.Operations']
['HS.IHE.XDSb.Repository.Operations']
['To_Cerner_Results']
['To_Dictaphone']
['To_Intellilab']
['To_Lab']
['To_Radiology']
-- 

2. SQL クエリで本番環境内のアクティブな項目を調べる

SELECT Name, ClassName 
FROM Ens_Config.Item 
WHERE Production = 'Hospital.HospitalProduction' 
  AND Enabled = 1

-- 
Name                                    ClassName
To_Radiology                            EnsLib.HL7.Operation.FileOperation
To_Lab                                  EnsLib.HL7.Operation.FileOperation
To_Dictaphone                           EnsLib.HL7.Operation.FileOperation
From_Cerner_ADT                         EnsLib.HL7.Service.FileService
From_Cerner_ADT_Router                  EnsLib.HL7.MsgRouter.RoutingEngine
From_Radiology_Results_Router           EnsLib.HL7.MsgRouter.RoutingEngine
From_Lab_Results_Router                 EnsLib.HL7.MsgRouter.RoutingEngine
From_Dictaphone_Results_Router          EnsLib.HL7.MsgRouter.RoutingEngine
To_Intellilab                           EnsLib.HL7.Operation.FileOperation
To_Cerner_Results                       EnsLib.HL7.Operation.FileOperation
From_Cerner_Orders_Router               EnsLib.HL7.MsgRouter.RoutingEngine
From_Athena_Multi_Router                EnsLib.HL7.MsgRouter.RoutingEngine
HS.IHE.XDSb.DocumentSource.Operations   HS.IHE.XDSb.DocumentSource.Operations
-- 

3. 本番環境内の項目にアクセスするオブジェクト

// ObjectScript 
// アクティブな本番環境内のすべての項目を取得するアクセス
// 項目のリストを返す
ClassMethod ListItemsInProduction()
{
    Set productionName =  ##class(Ens.Director).GetActiveProductionName()
    Set items = []
    &sql(Declare curr cursor FOR Select Name into :newId from Ens_Config.Item Where Production = :productionName)
    &sql(OPEN curr)
    For {
        &sql(FETCH curr)
        Quit:SQLCODE
        Do items.%Push(newId)
    }
    &sql(CLOSE curr)
    quit items
}

>>> zw ##class(ISC.SE.ProductionTools).ListItemsInProduction()

["From_Athena_Multi","From_Athena_Multi_Router","From_Cerner_ADT","From_Cerner_ADT_Router","From_Cerner_Orders","From_Cerner_Orders_Router","From_Dictaphone_Results","From_Dictaphone_Results_Router"
,"From_Lab_Results","From_Lab_Results_Router","From_Radiology_Results","From_Radiology_Results_Router","HS.IHE.XDSb.DocumentSource.Operations","HS.IHE.XDSb.Repository.Operations","To_Cerner_Results"
,"To_Dictaphone","To_Intellilab","To_Lab","To_Radiology"]  ; <DYNAMIC ARRAY>
# Python
# Get Dataframe of active production items

import os
# Set environment variables
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris

def getActiveProductionItems():
    productionName = iris.cls('Ens.Director').GetActiveProductionName()
    df = iris.sql.exec("SELECT Name FROM Ens_Config.Item Where Production = '{}'".format(productionName))
    return df

production_items_df = getActiveProductionItems().dataframe()

#                                      name
# 0                       From_Athena_Multi
# 1                From_Athena_Multi_Router
# 2                         From_Cerner_ADT
# 3                  From_Cerner_ADT_Router
# 4                      From_Cerner_Orders
# 5               From_Cerner_Orders_Router
# 6                 From_Dictaphone_Results
# 7          From_Dictaphone_Results_Router
# 8                        From_Lab_Results
# 9                 From_Lab_Results_Router
# 10                 From_Radiology_Results
# 11          From_Radiology_Results_Router
# 12  HS.IHE.XDSb.DocumentSource.Operations
# 13      HS.IHE.XDSb.Repository.Operations
# 14                      To_Cerner_Results
# 15                          To_Dictaphone
# 16                          To_Intellilab
# 17                                 To_Lab
# 18                           To_Radiology

API 経由で本番環境を操作する

1. コンポーネントを追加する

// ObjectScript
set productionName = ##class(Ens.Director).GetActiveProductionName()
//新しい xml ファイルサービスを作成
set classname="EnsLib.XML.FileService"  //この項目のクラス
set name="NewService"           //構成名
set item=##class(Ens.Config.Item).%New(classname)

set item.Name=name
set item.Comment = "Test Service"
set item.PoolSize = "1"
set item.Enabled = 1
do item.%Save()
//  
// 本番環境クラスを開く
// prod="Test.configtest" を設定   //本番環境名を手動で設定
// または
set prod = productionName
set prodObj=##class(Ens.Config.Production).%OpenId(prod)
// 新しい項目を保存
set tSC=prodObj.Items.Insert(item)
set tSC=prodObj.SaveToClass(item)
set tSC=prodObj.%Save()

// 上記から項目を削除
set tSC = prodObj.RemoveItem(item)
set tSC = prodObj.SaveToClass()
set tSC=prodObj.%Save()
# Python
import os
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris
active_production = iris.cls('Ens.Director').GetActiveProductionName()
print("Current Production {}".format(active_production))

# コンポーネントに関するメタデータ
classname="EnsLib.XML.FileService"   # この項目のクラス
name="NewService"                    # 構成名
item=iris.cls('Ens.Config.Item')._New(classname) # 新しいコンポーネントを作る
item.Name=name
item.Comment = "Test Service"
item.PoolSize = "1"
item.Enabled = 1
item._Save()

# 本番環境クラスを開く
# prod="Test.configtest"    # 本番環境名を手動で設定
# または上記のアクティブな本番環境名を使用
prod = active_production

prodObj=iris.cls('Ens.Config.Production')._OpenId(prod)
# 項目を挿入したら本番環境を保存
tSC=prodObj.Items.Insert(item)
tSC=prodObj.SaveToClass(item)
tSC=prodObj._Save()

# 上記から項目を削除
tSC = prodObj.RemoveItem(item)
tSC = prodObj.SaveToClass()
tSC=prodObj._Save()

2. コンポーネントを無効化/有効化する

// ObjectScript
set productionName = ##class(Ens.Director).GetActiveProductionName()
set itemName = "My.Inbound.HL7"
// 項目の有効化に必要
Set componentName = productionName _ "||" _ itemName _ "|"
// 無効化または有効化
Set enable = 1 // または 0
Do ##class(Ens.Director).EnableConfigItem(componentName, enable, 1)

/// 本番環境内で構成項目を有効化または無効化します。 本番環境は実行中であってもなくても構いません。
/// pConfigItemName 引数は、有効化または無効化される構成項目名を指定します。
/// 同じ構成名を持つ項目が複数一致し、そのいずれかがすでに有効化されている場合は、 
///  pEnable=1 オプションの効果はなく、pEnable=0 オプションによって実行中の一致する
///   本番環境項目が無効化されます。実行中でない場合は、最初に一致する有効な項目が無効化されます。
///   
/// 構成項目名の仕様の文字列の完全な構文については、Ens.Director.ParseConfigName() メソッドをご覧ください。
ClassMethod EnableConfigItem(pConfigItemName As %String, pEnable As %Boolean = 1, pDoUpdate As %Boolean = 1)
# Python
import os
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'
import iris

active_production = iris.cls('Ens.Director').GetActiveProductionName()
item_name = "My.Inbound.HL7"
componentName = active_production + "||" + item_name + "|"

enable = 1 # or 0
iris.cls('Ens.Director').EnableConfigItem(componentName, enable, 1)

API による本番環境ステータス

// ObjectScript
/// このメソッドは、出力パラメーター経由で本番環境のステータスを返します。
/// pProductionName: ステータスが running、suspended、または troubled の場合に、その本番環境名を返します。
/// pState: 本番環境のステータスを出力します。 有効な値:
///          $$$eProductionStateRunning == 1
///          $$$eProductionStateStopped == 2
///          $$$eProductionStateSuspended == 3
///          $$$eProductionStateTroubled == 4
Set sc = ##class(Ens.Director).GetProductionStatus(.productionName, .productionState) 
Write productionName, " -- ", productionState
import os
# ネームスペースを難しい方法で設定
os.environ['IRISNAMESPACE'] = 'DEMONSTRATION'

import iris

# 出力変数を使用したテスト2
productionName, productionState = iris.ref('productionName'), iris.ref('productionState')
status = iris.cls('Ens.Director').GetProductionStatus(productionName, productionState) 

print("Status: {}".format(status))
# .value を表示
print("Production: {}".format(productionName.value))
# .value を表示
print("Production State: {}".format(productionState.value))
0
0 204
記事 Toshihiko Minamoto · 9月 10, 2022 49m read


このフォーメーション私の GitHub にあり、30 分で csv ファイルと txt ファイルの読み取りと書き込み方法、Postgres を使ったIRIS データベースリモートデータベースの挿入とアクセス方法、FLASK API の使用方法について説明します。これらすべてに、PEP8 命名規則に従った、Python のみのインターオペラビリティフレームワークを使用します。

このフォーメーションは、ほとんどをコピー&ペースト操作で実行でき、グローバル演習を行う前に、ステップごとの操作が説明されています。
記事のコメント欄、Teams、またはメール(lucas.enard@intersystems.com)でご質問にお答えします。

このフォーメーションに関するあらゆる点において、ご意見やご感想をお送りいただけると幸いです。

1. Ensemble / Interoperability のフォーメーション

このフォーメーションでは、Python および特に以下を使用した InterSystems のインターオペラビリティフレームワークを学習することを目標としています。

  • 本番環境
  • メッセージ
  • ビジネスオペレーション
  • アダプター
  • ビジネスプロセス
  • ビジネスサービス
  • REST サービスと運用

目次:

2. フレームワーク

以下は、IRIS フレームワークです。

フレームワーク全体図

IRIS 内部のコンポーネントは、本番環境を表します。 インバウンドアダプターとアウトバウンドアダプターは、様々な種類のフォーマットをデータベースの入力と出力として使用できるようにします。
複合アプリケーションにより、REST サービスなどの外部アプリケーションを通じて本番環境にアクセスできます。

これらのコンポーネントを繋ぐ矢印はメッセージで、 リクエストかレスポンスを表します。

3. フレームワークの適用

ここでは、CSV ファイルから行を読み取り、IRIS データベースに .txt ファイルで保存します。

次に、外部データベースにオブジェクトを保存できるようにするオペレーションを db-api を使って追加します。 このデータベースは Docker コンテナに配置されており、Postgres を使用します。

最後に、複合アプリケーションを使用して、新しいオブジェクトをデータベースに挿入する方法またはこのデータベースを照会する方法を確認します(ここでは、REST サービスを使用します)。

この目的に合わせて構成されたフレームワークは、以下のようになります。

WIP 適応したフレームワーク

4. 前提条件

このフォーメーションでは、以下の項目が必要です。

5. セットアップ

5.1. Docker コンテナ

InterSystems イメージにアクセスするために、次の URL に移動してください: http://container.intersystems.com。 InterSystems の資格情報にリンクすると、レジストリに接続するためのパスワードを取得できます。 Docker の VSCode アドオンのイメージタブで、[レジストリを接続]を押し、汎用レジストリとして上記の URL(http://container.intersystems.com)を入力すると、資格情報の入力を求められます。 このログインは通常のログインですが、パスワードはウェブサイトから取得したものを使用します。

これが済むと、コンテナを構築・作成(指定された docker-compose.ymlDockerfile を使用)できるようになります。

5.2. 管理ポータルと VSCode

このリポジトリは、VS Code 対応です。

ローカルにクローンした formation-template-python を VS Code で開きます。

指示されたら(右下に表示)、推奨される拡張機能をインストールしてください。

5.3. コンテナ内でフォルダを開く

コーディングする前に、コンテナ内部にアクセスしていることが非常に重要です
これには、docker が VSCode を開く前に有効である必要があります。
次に VSCode 内で指示されたら(右下に表示)、コンテナ内のフォルダを開き直すと、その中にある Python コンポーネントを使用できるようになります。
これを初めて行う場合、コンテナの準備が整うまで数分かかる場合があります。

詳細情報はこちらをご覧ください。

アーキテクチャ


リモートのフォルダを開くと、その中で開く VS Code とターミナルで、コンテナ内の Python コンポーネントを使用できます。 /usr/irissys/bin/irispython を使用するように構成してください。

Pythonインタープリター

5.4. コンポーネントの登録

本番環境に対して Python で作成しているコンポーネントを登録するには、grongier.pex._utils モジュールから register_component 関数を使用する必要があります。

重要: コンポーネントはすでに登録済みです(グローバル演習を除く)。
情報までに、またグローバル演習で使用できるように、以下の手順でコンポーネントを登録します。
これには、プロジェクトで作業している際に、最初に組み込み Python コンソールを使用して手動でコンポーネントを追加することをお勧めします。

これらのコマンドは、misc/register.py ファイルにあります。
このコマンドを使用するには、まずコンポーネントを作成してから、VSCode でターミナルを起動する必要があります(5.25.3 の手順を実行している場合は、自動的にコンテナ内に移動しています)。
IrisPython コンソールを起動するには、以下のように入力します。

/usr/irissys/bin/irispython

次に、以下を入力します。

from grongier.pex._utils import register_component

そして、以下のようにして、コンポーネントを登録できます。

register_component("bo","FileOperation","/irisdev/app/src/python/",1,"Python.FileOperation")

この行は、bo モジュール内にコーディングされている FileOperation クラスを登録します。このファイルは /irisdev/app/src/python/(このコースに従って作業している場合のパス)にあり、管理ポータルでは Python.FileOperation という名前を使用しています。

コンポーネントが登録済みである際にこのファイルの名前、クラスまたはパスを変更しない場合、VSCode でそれらを変更することが可能です。登録し直す必要はありません。 管理ポータルでの再起動は、必ず行ってください。

5.5. 完成ファイル

フォーメーションのある時点でやり方がわからなくなったり、さらに説明が必要となった場合は、GitHub の solution ブランチにすべての正しい内容と動作する本番環境をご覧いただけます。

6. 本番環境

本番環境は、Iris 上のすべての作業の土台であり、サービスプロセス、およびオペレーションをまとめるフレームワークの外殻として考える必要があります。
本番環境内のすべては関数を継承します。この関数は、このクラスのインスタンスの作成時に解決する on_init 関数と、インスタンスがキルされたときに解決する on_tear_down 関数です。 これは、書き込みを行うときに変数を設定する際、または使用された開いているファイルをクローンする際に役立ちます。

ほぼすべてのサービス、プロセス、およびオペレーションを持つ本番環境は、すでに作成済みであることに注意してください。
指示されたら、ユーザー名の SuperUser とパスワードの SYS を使用して接続してください。

本番環境が開いていない場合は、[Interoperability] > [Configure] メニューに移動して、[Production] をクリックし、 次に [Open] をクリックして iris / Production を選択します。


これを行ったら、ビジネスオペレーションに直接進むことができます。


ただし、本番環境の作成方法に興味がある場合は、以下のようにして作成することができます。
管理ポータルに移動し、ユーザー名: SuperUser、パスワード: SYS を使用して接続します。
次に、[Interoperability] と [Configure] メニューに進みます。

本番環境メニュー

次に、[New] を押して [Formation] パッケージを選択し、本番環境の名前を設定します。

本番環境の作成

本番環境を作成した直後、[Operations] セクションの真上にある [Production Settings(本番環境の設定)] をクリックする必要があります。 右のサイドバーメニューで、[Settings] タブの [Development and Debugging(開発とデバッグ)] で [Testing Enabled(テストを有効)] をアクティブにします(忘れずに [Apply] を押してください)。

本番環境のテスト

この最初の本番環境で、ビジネスオペレーションを追加していきます。

7. ビジネスオペレーション

ビジネスオペレーション(BO)は、IRIS から外部アプリケーション/システムにリクエストを送信できるようにする特定のオペレーションです。 必要なものを IRIS に直接保存するためにも使用できます。
BO には、このインスタンスがソースからメッセージを受信するたびに呼び出される on_message 関数もあるため、フレームワークで確認できるように、情報を外部クライアントと送受信することが可能です。

これらのオペレーションは、VSCode でローカルに作成します。つまり、src/python/bo.py ファイルです。
このファイルを保存すると、IRIS でコンパイルされます。

ここでの最初のオペレーションでは、メッセージのコンテンツをローカルデータベースに保存し、同じ情報をローカルの .txt ファイルに書き込みます。

まずは、このメッセージを保存する方法を作成する必要があります。

7.1. オブジェクトクラスの作成

dataclass を使用して、メッセージの情報を格納することにします。

すでに存在する src/python/obj.py ファイルを以下のようにします。
インポート:

from dataclasses import dataclass

コード:

@dataclass
class Formation:
    id_formation:int = None
    nom:str = None
    salle:str = None

@dataclass
class Training:
    name:str = None
    room:str = None

Formation クラスは、csv の情報を格納して「8. ビジネスプロセス」に送信する Python オブジェクトとして使用し、Training クラスは、「8. ビジネスプロセス」から複数のオペレーションに情報を送信し、Iris データベースに保存するか .txt ファイルに書き込むために使用されます。

7.2. メッセージクラスの作成

これらのメッセージには、7.1 で作成された obj.py ファイルにある Formation オブジェクトまたは Training オブジェクトが含まれます。

メッセージ、リクエスト、およびレスポンスはすべて grongier.pex.Message クラスの継承であることに注意してください。

すでに存在する src/python/msg.py ファイルを以下のようにします。
インポート:

from dataclasses import dataclass
from grongier.pex import Message

from obj import Formation,Training

コード:

@dataclass
class FormationRequest(Message):
    formation:Formation = None

@dataclass
class TrainingRequest(Message):
    training:Training = None

繰り返しますが、FormationRequest クラスは、csv の情報を格納して「8. ビジネスプロセス」に送信するメッセージとして使用し、TrainingRequest クラスは、「8. ビジネスプロセス」から複数のオペレーションに情報を送信し、Iris データベースに保存するか .txt ファイルに書き込むために使用されます。

7.3. オペレーションの作成

必要な要素がすべて揃ったので、オペレーションを作成できるようになりました。
すべてのビジネスオペレーションは、grongier.pex.BusinessOperation クラスを継承していることに注意してください。
すべてのオペレーションは、src/python/bo.py に保存されます。これらを区別できるよう、ファイルに現時点で確認できるように複数のクラスを作成する必要があります。オペレーションのすべてのクラスはすでに存在していますが、現時点ではほぼ空の状態です。

オペレーションがメッセージ/リクエストを受信すると、各関数のシグネチャに指定されたメッセージ/リクエストの種類に応じて自動的に正しい関数にメッセージ/リクエストを送信します。 メッセージ/リクエストの種類が処理されない場合は、on_message 関数に転送されます。

すでに存在する src/python/bo.py ファイルを以下のようにします。
インポート:

from grongier.pex import BusinessOperation
import os
import iris

from msg import TrainingRequest,FormationRequest

FileOperation クラスのコード:

class FileOperation(BusinessOperation):
    """
    トレーニングまたは患者をファイルに書き込むオペレーションです。
    """
    def on_init(self):
        """
        現在の作業ディレクトリを、オブジェクトの path 属性に指定されたディレクトリか、path 属性が指定されていない場合は /tmp ディレクトリに変更します。 
        また、filename 属性が設定されていない場合は、toto
.csv に設定します。
        :return: None
        """
        if hasattr(self,'path'):
            os.chdir(self.path)
        else:
            os.chdir("/tmp")
        return None

    def write_training(self, request:TrainingRequest):
        """
        ファイルにトレーニングを書き込みます。

        :param request: The request message
        :type request: TrainingRequest
        :return: None
        """
        romm = name = ""
        if request.training is not None:
            room = request.training.room
            name = request.training.name
        line = room+" : "+name+"\n"
        filename = 'toto.csv'
        self.put_line(filename, line)
        return None

    def on_message(self, request):
        return None


    def put_line(self,filename,string):
        """
        ファイルを開き、文字列を追加し、ファイルを閉じます。

        :param filename: The name of the file to write to
        :param string: The string to be written to the file
        """
        try:
            with open(filename, "a",encoding="utf-8",newline="") as outfile:
                outfile.write(string)
        except Exception as error:
            raise error

ご覧のとおり、FileOperationmsg.TrainingRequest タイプのメッセージを受信すると、request のシグネチャが TrainingRequest であるため、write_training 関数に送信されます。
この関数では、メッセージが格納する情報が toto.csv ファイルに書き込まれます。

path はオペレーションのパラメーターであるため、filename を管理ポータルで直接変更できる変数にし、基本値を toto.csv とすることができます。
このようにするには、on_init 関数を以下のように編集する必要があります。

    def on_init(self):
        if hasattr(self,'path'):
            os.chdir(self.path)
        else:
            os.chdir("/tmp")
        if not hasattr(self,'filename'):
            self.filename = 'toto.csv'
        return None

次に、オペレーションに直接コーディングして filename = 'toto.csv' を使用する代わりに、self.filename を呼び出します。
すると、write_training 関数は、以下のようになります。

    def write_training(self, request:TrainingRequest):
        romm = name = ""
        if request.training is not None:
            room = request.training.room
            name = request.training.name
        line = room+" : "+name+"\n"
        self.put_line(self.filename, line)
        return None

独自の filename の選択方法にいては、「7.5 テスト」をご覧ください。

情報を .txt ファイルに書き込めるようになりましたが、iris データベースはどうなっているでしょうか?
src/python/bo.py ファイルでは、IrisOperation クラスのコードは以下のようになっています。

class IrisOperation(BusinessOperation):
    """
    iris データベースにトレーニングを書き込むオペレーション
    """

    def insert_training(self, request:TrainingRequest):
        """
        `TrainingRequest` オブジェクトを取り、新しい行を `iris.training` テーブルに挿入し、
        `TrainingResponse` オブジェクトを返します

        :param request: 関数に渡されるリクエストオブジェクト
        :type request: TrainingRequest
        :return: TrainingResponse メッセージ
        """
        sql = """
        INSERT INTO iris.training
        ( name, room )
        VALUES( ?, ? )
        """
        iris.sql.exec(sql,request.training.name,request.training.room)
        return None

    def on_message(self, request):
        return None

ご覧のとおり、IrisOperationmsg.TrainingRequest タイプのメッセージを受信すると、このメッセージが保有する情報は、iris.sql.exec IrisPython 関数によって SQL クエリに変換されて実行されます。 このメソッドによって、メッセージは IRIS ローカルデータベースに保存されます。


これらのコンポーネントは、事前に本番環境に登録済みです。

情報までに、コンポーネントを登録する手順は、5.4. に従い、以下を使用します。

register_component("bo","FileOperation","/irisdev/app/src/python/",1,"Python.FileOperation")

および、以下を使用します。

register_component("bo","IrisOperation","/irisdev/app/src/python/",1,"Python.IrisOperation")

7.4. 本番環境へのオペレーションの追加

オペレーションは、こちらで事前に登録済みです。
ただし、オペレーションを新規作成する場合は、手動で追加する必要があります。

今後の参考までに、オペレーションの登録手順を説明します。
登録には、管理ポータルを使用します。 [Operations] の横にある [+] 記号を押すと、[Business Operation Wizard(ビジネスオペレーションウィザード)] が開きます。
そのウィザードで、スクロールメニューから作成したばかりのオペレーションクラスを選択します。

オペレーションの作成

新しく作成したすべてのオペレーションに対して必ず実行してください!

7.5. テスト

オペレーションをダブルクリックすると、オペレーションが有効化されるか、再起動して変更内容が保存されます。
重要: この無効化して有効化し直す手順は、変更内容を保存する上で非常に重要な手順です。
重要: その後で、Python.IrisOperationオペレーションを選択し、右のサイドバーメニューの [Actions] タブに移動すると、オペレーションテストすることができます。
(うまくいかない場合は、テストを有効化し、本番環境が開始していることを確認してから、本番環境をダブルクリックして再起動をクリックし、オペレーションをリロードしてください)。

IrisOperation については、テーブルは自動的に作成済みです。 情報までに、これを作成するには、管理ポータルを使用します。[System Explorer(システムエクスプローラー)] > [SQL] > [Go] に移動して、Iris データベースにアクセスします。 次に、[Execute Query(クエリを実行)] を開始します。

CREATE TABLE iris.training (
    name varchar(50) NULL,
    room varchar(50) NULL
)

管理ポータルのテスト機能を使用して、前に宣言したタイプのメッセージをオペレーションに送信します。 すべてがうまくいけば、仮想トレースを表示すると、プロセスとサービスとオペレーション間で何が起きたかを確認できるようになります。
Request Type として使用した場合:

Grongier.PEX.Message

%classname として使用した場合:

msg.TrainingRequest

%json として使用した場合:

{
    "training":{
        "name": "name1",
        "room": "room1"
    }
}

ここでは、メッセージがプロセスによってオペレーションに送信され、オペレーションがレスポンス(空の文字列)を送り返すのを確認できます。
以下のような結果が得られます。 IrisOperation


FileOperation については、以下のように管理ポータルの %settingspath を入力できます(7.3.filename に関するメモに従った場合は、設定に filename を追加できます)。

path=/tmp/
filename=tata.csv

結果は以下のようになります。 FileOperation の設定


繰り返しますが、Python.FileOperationオペレーションを選択して、右サイドバーメニューの [Actions] タブに移動すると、オペレーションテストできます。
(うまくいかない場合は、テストを有効化し、本番環境が起動していることを確認してください)。
Request Type として使用した場合:

Grongier.PEX.Message

%classname として使用した場合:

msg.TrainingRequest

%json として使用した場合:

{
    "training":{
        "name": "name1",
        "room": "room1"
    }
}

結果は以下のようになります。 FileOperation


オペレーションが動作したかどうかを確認するには、toto.csv(7.3.filename に関するメモに従った場合は tata.csv)ファイルと Iris データベースにアクセスして変更内容を確認する必要があります。
次の手順を実行するには、コンテナの中に移動する必要がありますが、5.2.5.3 を実行した場合には、省略できます。
toto.csv にアクセスするには、ターミナルを開いて、以下を入力する必要があります。

bash
cd /tmp
cat toto.csv

または、必要であれば "cat tata.csv" を使用してください。
重要: ファイルが存在しない場合、管理ポータルでオペレーションを再起動していない可能性があります。
再起動するには、オペレーションをクリックして再起動を選択してください(または、無効化してからもう一度ダブルクリックして有効化してください)。
もう一度テストする必要があります。


Iris データベースにアクセスするには、管理ポータルにアクセスし、[System Explorer(システムエクスプローラー)] > [SQL] > [Go] を選択する必要があります。 次に、[Execute Query(クエリを実行)] を開始します。

SELECT * FROM iris.training

8. ビジネスプロセス

ビジネスプロセス(BP)は、本番環境のビジネスロジックです。 リクエストをプロセスしたり、本番環境の他のコンポーネントにそのリクエストをリレーしたリするために使用されます。
BP には、インスタンスがソースからリクエストを受信するたびに呼び出される on_request 関数もあるため、情報を受信して処理し、正しい BO に送信することができます。

これらのプロセスは、VSCode でローカルに作成します。つまり、src/python/bp.py ファイルです。
このファイルを保存すると、IRIS でコンパイルされます。

8.1. 単純な BP

サービスから受信する情報を処理し、適切に配信するビジネスプロセスを作成しましょう。 オペレーションを呼び出す単純な BP を作成することにします。

この BP は情報をリダイレクトするだけであるため、これを Router と呼び、src/python/bp.py に作成します。
インポート:

from grongier.pex import BusinessProcess

from msg import FormationRequest, TrainingRequest
from obj import Training

コード:


class Router(BusinessProcess):

    def on_request(self, request):
        """
        リクエストを受信し、フォーメーションリクエストであるかを確認し、そうである場合は
        TrainingRequest リクエストを FileOperation と IrisOperation に送信します。IrisOperation が 1 を返すと、PostgresOperation に送信します。

        :param request: 受信したリクエストオブジェクト
        :return: None
        """
        if isinstance(request,FormationRequest):

            msg = TrainingRequest()
            msg.training = Training()
            msg.training.name = request.formation.nom
            msg.training.room = request.formation.salle

            self.send_request_sync('Python.FileOperation',msg)
            self.send_request_sync('Python.IrisOperation',msg)
        return None

Router は FormationRequest タイプのリクエストを受信し、TrainingRequest タイプのメッセージを作成して IrisOperationFileOperation オペレーションに送信します。 メッセージ/リクエストが求めているタイプのインスタンスでない場合、何も行わず、配信しません。


これらのコンポーネントは、事前に本番環境に登録済みです。

情報までに、コンポーネントを登録する手順は、5.4. に従い、以下を使用します。

register_component("bp","Router","/irisdev/app/src/python/",1,"Python.Router")

8.2. 本番環境へのプロセスの追加

プロセスは、こちらで事前に登録済みです。
ただし、プロセスを新規作成する場合は、手動で追加する必要があります。

今後の参考までに、プロセスの登録手順を説明します。
登録には、管理ポータルを使用します。 [Process] の横にある [+] 記号を押すと、[Business Process Wizard(ビジネスプロセスウィザード)] が開きます。
そのウィザードで、スクロールメニューから作成したばかりのプロセスクラスを選択します。

8.3. テスト

プロセスをダブルクリックすると、プロセスが有効化されるか、再起動して変更内容が保存されます。
重要: この無効化して有効化し直す手順は、変更内容を保存する上で非常に重要な手順です。
重要: その後で、プロセスを選択し、右のサイドバーメニューの [Actions] タブに移動すると、プロセステストすることができます。
(うまくいかない場合は、テストを有効化し、本番環境が開始していることを確認してから、本番環境をダブルクリックして再起動をクリックし、プロセスをリロードしてください)。

こうすることで、プロセスに msg.FormationRequest タイプのメッセージを送信します。 Request Type として使用した場合:

Grongier.PEX.Message

%classname として使用した場合:

msg.FormationRequest

%json として使用した場合:

{
    "formation":{
        "id_formation": 1,
        "nom": "nom1",
        "salle": "salle1"
    }
}

Router のテスト

すべてがうまくいけば、仮想トレースを表示すると、プロセスとサービスとプロセス間で何が起きたかを確認できるようになります。
ここでは、メッセージがプロセスによってオペレーションに送信され、オペレーションがレスポンスを送り返すのを確認できます。 Router の結果

9. ビジネスサービス

ビジネスサービス(BS)は、本番環境の中核です。 情報を収集し、ルーターに送信するために使用されます。 BS には、フレームワークの情報を頻繁に収集する on_process_input 関数もあるため、REST API やその他のサービス、またはサービス自体などの複数の方法で呼び出してサービスのコードをもう一度実行することが可能です。 BS には、クラスにアダプターを割り当てられる get_adapter_type 関数もあります。たとえば、Ens.InboundAdapter は、サービスがその on_process_input を 5 秒おきに呼び出すようにすることができます。

これらのサービスは、VSCode でローカルに作成します。つまり、python/bs.py ファイルです。
このファイルを保存すると、IRIS でコンパイルされます。

9.1. 単純な BS

CSV を読み取って、msg.FormationRequest として各行をルーターに送信するビジネスサービスを作成しましょう。

この BS は csv を読み取るため、これを ServiceCSV と呼び、src/python/bs.py に作成します。
インポート:

from grongier.pex import BusinessService

from dataclass_csv import DataclassReader

from obj import Formation
from msg import FormationRequest

コード:

class ServiceCSV(BusinessService):
    """
    csv ファイルを 5 秒おきに読み取り、メッセージとして各行を Python Router プロセスに送信します。
    """

    def get_adapter_type():
        """
        登録済みのアダプタ名
        """
        return "Ens.InboundAdapter"

    def on_init(self):
        """
        現在のファイルパスをオブジェクトの path 属性に指定されたパスに変更します。
        path 属性が指定されていない場合は '/irisdev/app/misc/' に変更します。
        :return: None
        """
        if not hasattr(self,'path'):
            self.path = '/irisdev/app/misc/'
        return None

    def on_process_input(self,request):
        """
        formation.csv ファイルを読み取り、各行のFormationRequest メッセージを作成し、
        Python.Router プロセスに送信します。

        :param request: リクエストオブジェクト
        :return: None
        """
        filename='formation.csv'
        with open(self.path+filename,encoding="utf-8") as formation_csv:
            reader = DataclassReader(formation_csv, Formation,delimiter=";")
            for row in reader:
                msg = FormationRequest()
                msg.formation = row
                self.send_request_sync('Python.Router',msg)
        return None

FlaskService はそのままにし、ServiceCSV のみを入力することをお勧めします。

ご覧のとおり、ServiceCSV は、独立して機能し、5 秒おき(管理ポータルのサービスの設定にある基本設定で変更できるパラメーター)に on_process_input を呼び出せるようにする InboundAdapter を取得します。

サービスは、5 秒おきに formation.csv を開き、各行を読み取って、Python.Router に送信される msg.FormationRequest を作成します。


これらのコンポーネントは、事前に本番環境に登録済みです。

情報までに、コンポーネントを登録する手順は、5.4. に従い、以下を使用します。

register_component("bs","ServiceCSV","/irisdev/app/src/python/",1,"Python.ServiceCSV")

9.2. 本番環境へのサービスの追加

サービスは、こちらで事前に登録済みです。
ただし、サービスを新規作成する場合は、手動で追加する必要があります。

今後の参考までに、サービスの登録手順を説明します。
登録には、管理ポータルを使用します。 [service] の横にある [+] 記号を押すと、[Business Service Wizard(ビジネスサービスウィザード)] が開きます。
そのウィザードで、スクロールメニューから作成したばかりのサービスクラスを選択します。

9.3. テスト

サービスをダブルクリックすると、サービスが有効化されるか、再起動して変更内容が保存されます。
重要: この無効化して有効化し直す手順は、変更内容を保存する上で非常に重要な手順です。
前に説明したように、サービスは 5 秒おきに自動的に開始するため、ここでは他に行うことはありません。
すべてがうまくいけば、視覚的トレースを表示すると、プロセスとサービスとプロセス間で何が起きたかを確認することができます。
ここでは、メッセージがサービスによってプロセスに送信され、プロセスによってオペレーションに送信され、オペレーションがレスポンスを送り返すのを確認できます。 サービス CSV の結果

10. db-api による外部データベースへのアクセス

このセクションでは、外部データベースにオブジェクトを保存するオペレーションを作成します。 db-api を使用し、その他の Docker コンテナをセットアップして Postgres を設定します。

10.1. 前提条件

Postgres を使用するには psycopg2 が必要です。これは、単純なコマンドで Postgres データベースに接続できるようにする Python モジュールです。
これは自動的に完了済みですが、情報までに説明すると、Docker コンテナにアクセスし、pip3 を使って psycopg2 をインストールします。
ターミナルを開始したら、以下を入力します。

pip3 install psycopg2-binary

または、requirements.txt にモジュールを追加して、コンテナを再構築できます。

10.2. 新しいオペレーションの作成

新しいオペレーションは、src/python/bo.py ファイルの他の 2 つのオペレーションの後に追加してください。 以下は、新しいオペレーションとインポートです。
インポート:

import psycopg2

コード:

class PostgresOperation(BusinessOperation):
    """
    トレーニングを Postgres データベースに書き込むオペレーションです。
    """

    def on_init(self):
        """
        Postgres データベースに接続して接続オブジェクトを初期化する関数です。
        :return: None
        """
        self.conn = psycopg2.connect(
        host="db",
        database="DemoData",
        user="DemoData",
        password="DemoData",
        port="5432")
        self.conn.autocommit = True

        return None

    def on_tear_down(self):
        """
        データベースへの接続を閉じます。
        :return: None
        """
        self.conn.close()
        return None

    def insert_training(self,request:TrainingRequest):
        """
        トレーニングを Postgre データベースに挿入します。

        :param request: 関数に渡されるリクエストオブジェクト
        :type request: TrainingRequest
        :return: None
        """
        cursor = self.conn.cursor()
        sql = "INSERT INTO public.formation ( name,room ) VALUES ( %s , %s )"
        cursor.execute(sql,(request.training.name,request.training.room))
        return None

    def on_message(self,request):
        return None

このオペレーションは、最初に作成したオペレーションに似ています。 msg.TrainingRequest タイプのメッセージを受信すると、psycopg モジュールを使用して、SQL リクエストを実行します。 これらのリクエストは、Postgres データベースに送信されます。

ご覧のとおり、接続はコードに直接書き込まれています。コードを改善するために、他のオペレーションで前に行ったようにし、hostdatabase、およびその他の接続情報を変数にすることができます。基本値を dbDemoData にし、管理ポータルで直接変更できるようにします。
これを行うには、以下のようにして on_init を変更します。

    def on_init(self):
        if not hasattr(self,'host'):
          self.host = 'db'
        if not hasattr(self,'database'):
          self.database = 'DemoData'
        if not hasattr(self,'user'):
          self.user = 'DemoData'
        if not hasattr(self,'password'):
          self.password = 'DemoData'
        if not hasattr(self,'port'):
          self.port = '5432'

        self.conn = psycopg2.connect(
        host=self.host,
        database=self.database,
        user=self.user,
        password=self.password,
        port=self.port)

        self.conn.autocommit = True

        return None


これらのコンポーネントは、事前に本番環境に登録済みです。

情報までに、コンポーネントを登録する手順は、5.4. に従い、以下を使用します。

register_component("bo","PostgresOperation","/irisdev/app/src/python/",1,"Python.PostgresOperation")

10.3. 本番環境の構成

オペレーションは、こちらで事前に登録済みです。
ただし、オペレーションを新規作成する場合は、手動で追加する必要があります。

今後の参考までに、オペレーションの登録手順を説明します。
登録には、管理ポータルを使用します。 [Operations] の横にある [+] 記号を押すと、[Business Operation Wizard(ビジネスオペレーションウィザード)] が開きます。
そのウィザードで、スクロールメニューから作成したばかりのオペレーションクラスを選択します。


その後、接続を変更する場合は、オペレーションの [parameter] ウィンドウで、[Python] の %settings に変更するパラメーターを追加すれば完了です。 詳細については、「7.5 テスト」の 2 つ目の画像をご覧ください。

10.4. テスト

オペレーションをダブルクリックすると、オペレーションが有効化されるか、再起動して変更内容が保存されます。
重要: この無効化して有効化し直す手順は、変更内容を保存する上で非常に重要な手順です。
重要: その後で、オペレーションを選択し、右のサイドバーメニューの [Actions] タブに移動すると、オペレーションテストすることができます。
(うまくいかない場合は、テストを有効化し、本番環境が開始していることを確認してから、本番環境をダブルクリックして再起動をクリックし、オペレーションをリロードしてください)。

PostGresOperation については、テーブルは自動的に作成済みです。

こうすることで、オペレーションに msg.TrainingRequest タイプのメッセージを送信します。 Request Type として使用した場合:

Grongier.PEX.Message

%classname として使用した場合:

msg.TrainingRequest

%json として使用した場合:

{
    "training":{
        "name": "nom1",
        "room": "salle1"
    }
}

以下のとおりです。 Postgres のテスト

仮想トレースをテストすると、成功が表示されます。

これで、外部データベースに接続することができました。

ここまで、ここに記載の情報に従ってきた場合、プロセスやサービスは新しい PostgresOperation を呼び出さない、つまり、管理ポータルのテスト機能を使用しなければ呼び出されないことを理解していることでしょう。

10.5. 演習

演習として、bo.IrisOperation がブール値を返すように変更し、そのブール値に応じて bp.Routerbo.PostgresOperation を呼び出すようにしてみましょう。
そうすることで、ここで新しく作成したオペレーションが呼び出されるようになります。

ヒント: これは、bo.IrisOperation レスポンスの戻り値のタイプを変更し、新しいメッセージ/レスポンスタイプに新しいブール値プロパティを追加して、bp.Router に if 操作を使用すると実現できます。

10.6. ソリューション

まず、bo.IrisOperation からのレスポンスが必要です。 src/python/msg.py の他の 2 つのメッセージの後に、以下のようにして新しいメッセージを作成します。
コード:

@dataclass
class TrainingResponse(Message):
    decision:int = None

次に、そのレスポンスによって、bo.IrisOperation のレスポンスを変更し、decision の値を 1 または 0 にランダムに設定します。
src/python/bo.py で 2 つのインポートを追加し、IrisOperation クラスを変更する必要があります。
インポート:

import random
from msg import TrainingResponse

コード:

class IrisOperation(BusinessOperation):
    """
    トレーニングを iris データベースに書き込むオペレーションです。
    """

    def insert_training(self, request:TrainingRequest):
        """
        `TrainingRequest` オブジェクトを取り、新しい行を`iris.training` テーブルに挿入し、
        `TrainingResponse` オブジェクトを返します。

        :param request: 関数に渡されるリクエストオブジェクト
        :type request: TrainingRequest
        :return: A TrainingResponse message
        """
        resp = TrainingResponse()
        resp.decision = round(random.random())
        sql = """
        INSERT INTO iris.training
        ( name, room )
        VALUES( ?, ? )
        """
        iris.sql.exec(sql,request.training.name,request.training.room)
        return resp

    def on_message(self, request):
        return None

次に、`src/python/bp.py` で `bp.Router` プロセスを変更します。ここでは、IrisOperation からのレスポンスが 1 の場合に PostgresOperation を呼び出すようにします。 新しいコードは以下のようになります。
class Router(BusinessProcess):

    def on_request(self, request):
        """
        リクエストを受け取り、フォーメーションリクエストであるかどうかをチェックします。
        その場合は、TrainingRequest リクエストを FileOperation と IrisOperation に送信し、IrisOperation が 1 を返すと PostgresOperation に送信します。

        :param request: 受信したリクエストオブジェクト
        :return: None
        """
        if isinstance(request,FormationRequest):

            msg = TrainingRequest()
            msg.training = Training()
            msg.training.name = request.formation.nom
            msg.training.room = request.formation.salle

            self.send_request_sync('Python.FileOperation',msg)

            form_iris_resp = self.send_request_sync('Python.IrisOperation',msg)
            if form_iris_resp.decision == 1:
                self.send_request_sync('Python.PostgresOperation',msg)
        return None

非常に重要: オペレーションの呼び出しには、send_request_async ではなく、必ず send_request_sync を使用する必要があります。そうでない場合、この操作はブール値のレスポンスを受け取る前に実行されます。


テストする前に、必ず変更したすべてのサービス、プロセス、およびオペレーションをダブルクリックして再起動してください。これを行わない場合、変更内容は適用されません。


テスト後、視覚的トレースで、csv で読み取られたおよそ半数のオブジェクトがリモートデータベースにも保存されていることがわかります。
bs.ServiceCSV を開始するだけでテストできることに注意してください。リクエストは自動的にルーターに送信され、適切に配信されます。
また、サービス、オペレーション、またはプロセスをダブルクリックしてリロードを押すか、VSCode で保存した変更を適用するには再起動を押す必要があることにも注意してください。

11. REST サービス

ここでは、REST サービスを作成して使用します。

11.1. 前提条件

Flask を使用するには、flask のインストールが必要です。これは、REST サービスを簡単に作成できるようにする Python モジュールです。 これは、自動的に実行済みですが、今後の情報までに説明すると、Docker コンテナ内にアクセスして iris python に flask をインストールします。 ターミナルを開始したら、以下を入力します。

pip3 install flask

または、requirements.txt にモジュールを追加して、コンテナを再構築できます。

11.2. サービスの作成

REST サービスを作成するには、API を本番環境にリンクするサービスが必要です。このために、src/python/bs.pyServiceCSV クラスの直後に新しい単純なサービスを作成します。

class FlaskService(BusinessService):

    def on_init(self):    
        """
        API の現在のターゲットをオブジェクトの target 属性に指定されたターゲットに変更します。
        または、target 属性が指定されていない場合は 'Python.Router' に変更します。
        :return: None
        """    
        if not hasattr(self,'target'):
            self.target = "Python.Router"        
        return None

    def on_process_input(self,request):
        """
        API から直接 Python.Router プロセスに情報を送信するために呼び出されます。
        :return: None
        """
        return self.send_request_sync(self.target,request)

このサービスに on_process_input を行うと、リクエストが Router に転送されます。


これらのコンポーネントは、事前に本番環境に登録済みです。

情報までに、コンポーネントを登録する手順は、5.4. に従い、以下を使用します。

register_component("bs","FlaskService","/irisdev/app/src/python/",1,"Python.FlaskService")


REST サービスを作成するには、Flask を使って getpost 関数を管理する API を作成する必要があります。 新しいファイルを python/app.py として作成してください。

from flask import Flask, jsonify, request, make_response
from grongier.pex import Director
import iris

from obj import Formation
from msg import FormationRequest


app = Flask(__name__)

# GET Infos
@app.route("/", methods=["GET"])
def get_info():
    info = {'version':'1.0.6'}
    return jsonify(info)

# GET all the formations
@app.route("/training/", methods=["GET"])
def get_all_training():
    payload = {}
    return jsonify(payload)

# POST a formation
@app.route("/training/", methods=["POST"])
def post_formation():
    payload = {} 

    formation = Formation()
    formation.nom = request.get_json()['nom']
    formation.salle = request.get_json()['salle']

    msg = FormationRequest(formation=formation)

    service = Director.CreateBusinessService("Python.FlaskService")
    response = service.dispatchProcessInput(msg)

    return jsonify(payload)

# GET formation with id
@app.route("/training/<int:id>", methods=["GET"])
def get_formation(id):
    payload = {}
    return jsonify(payload)

# PUT to update formation with id
@app.route("/training/<int:id>", methods=["PUT"])
def update_person(id):
    payload = {}
    return jsonify(payload)

# DELETE formation with id
@app.route("/training/<int:id>", methods=["DELETE"])
def delete_person(id):
    payload = {}  
    return jsonify(payload)

if __name__ == '__main__':
    app.run('0.0.0.0', port = "8081")

Flask API は Director を使用して、前述のものから FlaskService のインスタンスを作成してから適切なリクエストを送信することに注意してください。

上記の子k-度では、POST フォーメンション関数を作成しました。希望するなら、これまでに学習したものすべてを使用して、適切な情報を get/post するように、他の関数を作成することが可能です。ただし、これに関するソリューションは提供されていません。

11.3. テスト

Python Flask を使用して flask アプリを開始しましょう。
Flask app.py の開始方法

最後に、Router サービスをリロードしてから、任意の REST クライアントを使用してサービスをテストできます。

(Mozilla の RESTer として)REST サービスを使用するには、以下のようにヘッダーを入力する必要があります。

Content-Type : application/json

REST のヘッダー

ボディは以下のようになります。

{
    "nom":"testN",
    "salle":"testS"
}

REST のボディ

認証は以下のとおりです。
ユーザー名:

SuperUser

パスワード:

SYS

REST の認証

最後に、結果は以下のようになります。 REST の結果

12. グローバル演習

Iris DataPlatform とそのフレームワークのすべての重要な概念について学習したので、グローバル演習で腕試しをしましょう。この演習では、新しい BS と BP を作成し、BO を大きく変更して、新しい概念を Python で探ります。

12.1. 指示

こちらのエンドポイントhttps://lucasenard.github.io/Data/patients.json を使用して、患者と歩数に関する情報を自動的に取得するようにします。 次に、ローカルの csv ファイルに書き込む前に、各患者の平均歩数を計算します。

必要であれば、フォーメーション全体または必要な箇所を読むか、以下のヒントを使って、ガイダンスを得ることをお勧めします。

管理ポータルでコンポーネントにアクセスできるように、コンポーネントの登録を忘れずに行いましょう。

すべてを完了し、テストしたら、または演習を完了するのに十分なヒントを得られなかった場合は、全過程をステップごとに説明したソリューションをご覧ください。

12.2. ヒント

ここでは、演習を行うためのヒントを紹介します。
読んだ分だけヒントが得られてしまうため、必要な箇所のみを読み、毎回すべてを読まないようにすることをお勧めします。

たとえば、bs の「情報の取得」と「リクエストによる情報の取得」のみを読み、他は読まないようにしましょう。

12.2.1. bs

12.2.1.1. 情報の取得

エンドポイントから情報を取得するには、Python の requests モジュールを検索し、jsonjson.dumps を使用して文字列に変換してから bp に送信します。

12.2.1.2. リクエストによる情報の取得

オンライン Python Web サイトまたはローカルの Python ファイルを使用してリクエストを使用し、取得した内容をさらに深く理解するために、出力とそのタイプを出力します。

12.2.1.3. リクエストによる情報の取得とその使用

新しいメッセージタイプと情報を保持するオブジェクトタイプを作成し、プロセスに送信して平均を計算します。

12.2.1.4. 情報の取得のソリューション

リクエストを使用してデータを取得する方法と、この場合に部分的に、それをどう処理するかに関するソリューションです。

r = requests.get(https://lucasenard.github.io/Data/patients.json)
data = r.json()
for key,val in data.items():
    ...

繰り返しますが、オンライン Python Web サイトまたはローカルの Python ファイルでは、key、val、およびタイプを出力し、それらを使用して何をできるかを理解することが可能です。
json.dumps(val) を使用して val を格納してから、SendRequest の後にプロセスにいるときに、json.loads(request.patient.infos) を使用してその val を取得します(val の情報を patient.infos に格納した場合)。

12.2.2. bp

12.2.2.1. 平均歩数と dict

statistics は、算術演算を行うために使用できるネイティブライブラリです。

12.2.2.2. 平均歩数と dict: ヒント

Python のネイティブ map 関数では、たとえばリスト内または辞書内の情報を分離することができます。

list ネイティブ関数を使用して、map の結果をリストに変換し直すことを忘れないようにしましょう。

12.2.2.3. 平均歩数と dict: map を使用する

オンライン Python Web サイトまたはローカルの Python ファイルを使用して、以下のように、リストのリストまたは辞書のリストの平均を計算することができます。

l1 = [[0,5],[8,9],[5,10],[3,25]]
l2 = [["info",12],["bidule",9],[3,3],["patient1",90]]
l3 = [{"info1":"7","info2":0},{"info1":"15","info2":0},{"info1":"27","info2":0},{"info1":"7","info2":0}]

#最初のリストの最初の列の平均(0/8/5/3)
avg_l1_0 = statistics.mean(list(map(lambda x: x[0]),l1))

#最初のリストの 2 つ目列の平均(5/9/10/25)
avg_l1_1 = statistics.mean(list(map(lambda x: x[1]),l1))

#12/9/3/90 の平均
avg_l2_1 = statistics.mean(list(map(lambda x: x[1]),l2))

#7/15/27/7 の平均
avg_l3_info1 = statistics.mean(list(map(lambda x: int(x["info1"])),l3))

print(avg_l1_0)
print(avg_l1_1)
print(avg_l2_1)
print(avg_l3_info1)

12.2.2.4. 平均歩数と dict: 解答

リクエストに、日付と歩数の dict の json.dumps である infos 属性を持つ患者が保持されている場合、以下のようにして平均歩数を計算できます。

statistics.mean(list(map(lambda x: int(x['steps']),json.loads(request.patient.infos))))

12.2.3. bo

bo.FileOperation.WriteFormation に非常に似たものを使用できます。

bo.FileOperation.WritePatient のようなものです。

12.3. ソリューション

12.3.1. obj と msg

obj.py に以下を追加できます。

@dataclass
class Patient:
    name:str = None
    avg:int = None
    infos:str = None

msg.py に以下を追加できます。
インポート:

from obj import Formation,Training,Patient

コード:

@dataclass
class PatientRequest(Message):
    patient:Patient = None

この情報を単一の obj に保持し、get リクエストから得る dict の str を直接 infos 属性に入れます。 平均は、プロセスで計算されます。

12.3.2. bs

bs.py に以下を追加できます。 インポート:

import requests

コード:

class PatientService(BusinessService):

    def get_adapter_type():
        """
        登録されたアダプタの名前
        """
        return "Ens.InboundAdapter"

    def on_init(self):
        """
        API の現在のターゲットをオブジェクトの target 属性に指定されたターゲットに変更します。
        target 属性が指定されていない場合は、'Python.PatientProcess' に変更します。
        API の現在の api_url をオブジェクトの taget 属性に指定された api_url に変更します。
        api_url 属性が指定されていない場合は、'https://lucasenard.github.io/Data/patients.json' に変更します。
        :return: None
        """
        if not hasattr(self,'target'):
            self.target = 'Python.PatientProcess'
        if not hasattr(self,'api_url'):
            self.api_url = "https://lucasenard.github.io/Data/patients.json"
        return None

    def on_process_input(self,request):
        """
        API にリクエストを行い、検出される患者ごとに Patient オブジェクトを作成し、
        ターゲットに送信します。

        :param request: サービスに送信されたリクエスト
        :return: None
        """
        req = requests.get(self.api_url)
        if req.status_code == 200:
            dat = req.json()
            for key,val in dat.items():
                patient = Patient()
                patient.name = key
                patient.infos = json.dumps(val)
                msg = PatientRequest()
                msg.patient = patient                
                self.send_request_sync(self.target,msg)
        return None

ターゲットと api url 変数を作成します(on_init を参照)。
requests.getreq 変数に情報を入れた後、json で情報を抽出する必要があります。これにより dat が dict になります。
dat.items を使用して、患者とその情報を直接イテレートできます。
次に、patient オブジェクトを作成し、json データを文字列に変換する json.dumps を使用して val を文字列に変換し、patient.infos 変数に入れます。
次に、プロセスを呼び出す msg.PatientRequestmsg リクエストを作成します。

コンポーネントの登録を忘れずに行いましょう。 5.4. に従い、以下を使用します。

register_component("bs","PatientService","/irisdev/app/src/python/",1,"Python.PatientService")

12.3.3. bp

bp.py に以下を追加できます。 インポート:

import statistic

コード:

class PatientProcess(BusinessProcess):

    def on_request(self, request):
        """
        リクエストを取り、PatientRequest であるかをチェックします。その場合は、患者の平均歩数を計算し、
        リクエストを Python.FileOperation サービスに送信します。

        :param request: サービスに送信されたリクエストオブジェクト
        :return: None
        """
        if isinstance(request,PatientRequest):
            request.patient.avg = statistics.mean(list(map(lambda x: int(x['steps']),json.loads(request.patient.infos))))
            self.send_request_sync('Python.FileOperation',request)

        return None

取得したばかりのリクエストを取り、PatientRequest である場合は、歩数の平均を計算して、FileOperation に送信します。 これは患者の avg 変数に正しい情報を挿入します(詳細は、bp のヒントを参照してください)。

コンポーネントの登録を忘れずに行いましょう。 5.4. に従い、以下を使用します。

register_component("bp","PatientProcess","/irisdev/app/src/python/",1,"Python.PatientProcess")

12.3.4. bo

bo.py に以下を追加できます。FileOperation クラス内:

    def write_patient(self, request:PatientRequest):
        """
        患者の名前と平均歩数をファイルに書き込みます。

        :param request: リクエストメッセージ
        :type request: PatientRequest
        :return: None
        """
        name = ""
        avg = 0
        if request.patient is not None:
            name = request.patient.name
            avg = request.patient.avg
        line = name + " avg nb steps : " + str(avg) +"\n"
        filename = 'Patients.csv'
        self.put_line(filename, line)
        return None

前に説明したとおり、FileOperation は以前に登録済みであるため、もう一度登録する必要はありません。

12.4. テスト

7.4. を参照して、オペレーションを追加しましょう。

9.2. を参照して、サービスを追加しましょう。

次に、管理ポータルに移動し、前と同じように行います。 新しいサービスは、InboundAdapter を追加したため、自動的に実行されます。

toto.csv と同様にして、Patients.csv を確認してください。

12.5. グローバル演習のまとめ

この演習を通じて、メッセージ、サービス、プロセス、およびオペレーションの作成を学習し、理解することができました。
Python で情報をフェッチする方法とデータに対して単純なタスクを実行する方法を発見しました。

すべての完成ファイルは、GitHub の solution ブランチにあります。

13. まとめ

このフォーメーションを通じ、csv ファイルから行を読み取り、読み取ったデータを db-api を使ってローカル txt、IRIS データベース、および外部データベースに保存できる IrisPython のみを使用して、フル機能の本番環境を作成しました。
また、POST 動詞を使用して新しいオブジェクトを保存する REST サービスも追加しました。

InterSystems のインターオペラビリティフレームワークの主要要素を発見しました。

これには、Docker、VSCode、および InterSystems の IRIS 管理ポータルを使用して実行しました。

0
0 247
お知らせ Mihoko Iijima · 8月 1, 2022

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

InterSystems 技術文書ライティングコンテスト: Python エディションでは、素晴らしい記事の投稿がありました!

🌟 12 の投稿はこちら! 🌟

この記事ではコンテスト受講者を発表します 📢​​​​​​


0
0 126
記事 Megumi Kakechi · 7月 26, 2022 5m read

Embedded Python で Excel のデータを IRIS グローバルに格納する方法 では Excel データを pandas.DataFrame に取り込んで、それを InterSystems IRIS グローバルに保存する方法をご紹介しました。

今回は「lxml を使用し Web スクレイピングした表(テーブル)のデータを InterSystems IRIS グローバルに格納する」方法をご紹介します。


※以下は Windows 上の IRIS でのインストール方法になります。
 UNIX ベースのシステムでは、pip3 コマンドを使用してインストールします。詳細は ドキュメント をご覧ください。

最初に、irispip コマンドで必要なライブラリをインストールします。
今回は、pandas、lxml の2つのライブラリをインストールします。

>cd C:\InterSystems\IRIS\bin
C:\InterSystems\IRIS\bin>irispip install --target C:\InterSystems\IRIS\mgr\python pandas
C:\InterSystems\IRIS\bin>irispip install --target C:\InterSystems\IRIS\mgr\python lxml
0
0 287